ǰÑÔ
±¾ÎÄÖ÷Òª½éÉÜObjective-C¶ÔÏóÄ£Ð͵ÄʵÏÖϸ½Ú£¬ÒÔ¼°Objective-CÓïÑÔ¶ÔÏóÄ£ÐÍÖжÔisa
swizzlingºÍmethod swizzlingµÄÖ§³Ö¡£Ï£Íû±¾ÎÄÄܼÓÉîÄã¶ÔObjective-C¶ÔÏóµÄÀí½â¡£
ISAÖ¸Õë
Objective-CÊÇÒ»ÃÅÃæÏò¶ÔÏóµÄ±à³ÌÓïÑÔ¡£Ã¿Ò»¸ö¶ÔÏó¶¼ÊÇÒ»¸öÀàµÄʵÀý¡£ÔÚObjective-CÓïÑÔµÄÄÚ²¿£¬Ã¿Ò»¸ö¶ÔÏó¶¼ÓÐÒ»¸öÃûΪisaµÄÖ¸Õ룬ָÏò¸Ã¶ÔÏóµÄÀࡣÿһ¸öÀàÃèÊöÁËһϵÁÐËüµÄʵÀýµÄÌØµã£¬°üÀ¨³ÉÔ±±äÁ¿µÄÁÐ±í£¬³ÉÔ±º¯ÊýµÄÁбíµÈ¡£Ã¿Ò»¸ö¶ÔÏ󶼿ÉÒÔ½ÓÊÜÏûÏ¢£¬¶ø¶ÔÏóÄܹ»½ÓÊÕµÄÏûÏ¢ÁбíÊDZ£´æÔÚËüËù¶ÔÓ¦µÄÀàÖС£
ÔÚXCodeÖа´Shift + Command + O, È»ºóÊäÈëNSObject.hºÍobjc.h£¬¿ÉÒÔ´ò¿ªNSObjectµÄ¶¨ÒåÍ·Îļþ£¬Í¨¹ýÍ·ÎļþÎÒÃÇ¿ÉÒÔ¿´µ½£¬NSObject¾ÍÊÇÒ»¸ö°üº¬isaÖ¸ÕëµÄ½á¹¹Ì壬ÈçÏÂͼËùʾ£º

°´ÕÕÃæÏò¶ÔÏóÓïÑÔµÄÉè¼ÆÔÔò£¬ËùÓÐÊÂÎï¶¼Ó¦¸ÃÊǶÔÏó£¨ÑϸñÀ´ËµObjective-C²¢Ã»ÓÐÍêÈ«×öµ½ÕâÒ»µã£¬ÒòΪËüÓÐÏóint,
doubleÕâÑùµÄ¼òµ¥±äÁ¿ÀàÐÍ£©¡£ÔÚObjective-CÓïÑÔÖУ¬Ã¿Ò»¸öÀàʵ¼ÊÉÏÒ²ÊÇÒ»¸ö¶ÔÏó¡£Ã¿Ò»¸öÀàÒ²ÓÐÒ»¸öÃûΪisaµÄÖ¸Õ롣ÿһ¸öÀàÒ²¿ÉÒÔ½ÓÊÜÏûÏ¢£¬ÀýÈç[NSObject
alloc]£¬¾ÍÊÇÏòNSObjectÕâ¸öÀà·¢ËÍÃûΪallocÏûÏ¢¡£
ÔÚXCodeÖа´Shift + Command + O, È»ºóÊäÈëruntime.h£¬¿ÉÒÔ´ò¿ªClassµÄ¶¨ÒåÍ·Îļþ£¬Í¨¹ýÍ·ÎļþÎÒÃÇ¿ÉÒÔ¿´µ½£¬ClassÒ²ÊÇÒ»¸ö°üº¬isaÖ¸ÕëµÄ½á¹¹Ì壬ÈçÏÂͼËùʾ¡££¨Í¼ÖгýÁËisaÍ⻹ÓÐÆäËü³ÉÔ±±äÁ¿£¬µ«ÄÇÊÇΪÁ˼æÈÝ·Ç2.0°æµÄObjective-CµÄÒÅÁôÂß¼£¬´ó¼Ò¿ÉÒÔºöÂÔËü¡££©

ÒòΪÀàÒ²ÊÇÒ»¸ö¶ÔÏó£¬ÄÇËüÒ²±ØÐëÊÇÁíÒ»¸öÀàµÄʵÁУ¬Õâ¸öÀà¾ÍÊÇÔªÀà(metaclass)¡£ÔªÀà±£´æÁËÀà·½·¨µÄÁÐ±í¡£µ±Ò»¸öÀà·½·¨±»µ÷ÓÃʱ£¬ÔªÀà»áÊ×ÏȲéÕÒËü±¾ÉíÊÇ·ñÓиÃÀà·½·¨µÄʵÏÖ£¬Èç¹ûûÓУ¬Ôò¸ÃÔªÀà»áÏòËüµÄ¸¸Àà²éÕҸ÷½·¨£¬Ö±µ½Ò»Ö±ÕÒµ½¼Ì³ÐÁ´µÄÍ·¡£
ÔªÀà(metaclass)Ò²ÊÇÒ»¸ö¶ÔÏó£¬ÄÇôԪÀàµÄisaÖ¸ÕëÓÖÖ¸ÏòÄÄÀïÄØ£¿ÎªÁËÉè¼ÆÉϵÄÍêÕû£¬ËùÓеÄÔªÀàµÄisaÖ¸Õë¶¼»áÖ¸ÏòÒ»¸ö¸ùÔªÀà(root
metaclass)¡£¸ùÔªÀà(root metaclass)±¾ÉíµÄisaÖ¸ÕëÖ¸Ïò×Ô¼º£¬ÕâÑù¾ÍÐгÉÁËÒ»¸ö±Õ»·¡£ÉÏÃæÌáµ½£¬Ò»¸ö¶ÔÏóÄܹ»½ÓÊÕµÄÏûÏ¢ÁбíÊDZ£´æÔÚËüËù¶ÔÓ¦µÄÀàÖеġ£ÔÚʵ¼Ê±à³ÌÖУ¬ÎÒÃǼ¸ºõ²»»áÓöµ½ÏòÔªÀà·¢ÏûÏ¢µÄÇé¿ö£¬ÄÇËüµÄisaÖ¸ÕëÔÚʵ¼ÊÉϺÜÉÙÓõ½¡£²»¹ýÕâôÉè¼Æ±£Ö¤ÁËÃæÏò¶ÔÏóµÄ¸É¾»£¬¼´ËùÓÐÊÂÎï¶¼ÊǶÔÏ󣬶¼ÓÐisaÖ¸Õë¡£
ÎÒÃÇÔÙÀ´¿´¿´¼Ì³Ð¹ØÏµ£¬ÓÉÓÚÀà·½·¨µÄ¶¨ÒåÊDZ£´æÔÚÔªÀà(metaclass)ÖУ¬¶ø·½·¨µ÷ÓõĹæÔòÊÇ£¬Èç¹û¸ÃÀàûÓÐÒ»¸ö·½·¨µÄʵÏÖ£¬ÔòÏòËüµÄ¸¸Àà¼ÌÐø²éÕÒ¡£ËùÒÔ£¬ÎªÁ˱£Ö¤¸¸ÀàµÄÀà·½·¨¿ÉÒÔÔÚ×ÓÀàÖпÉÒÔ±»µ÷Óã¬ËùÒÔ×ÓÀàµÄÔªÀà»á¼Ì³Ð¸¸ÀàµÄÔªÀ࣬»»¶øÑÔÖ®£¬Àà¶ÔÏóºÍÔªÀà¶ÔÏóÓÐ×ÅͬÑùµÄ¼Ì³Ð¹ØÏµ¡£
ÎÒºÜÏë°Ñ¹ØÏµËµÇå³þһЩ£¬µ«ÊÇÕâ¿é¶ùȷʵÓеãÈÆ£¬ÏÂÃæÕâÕÅͼ»òÐíÄܹ»Èôó¼Ò¶ÔisaºÍ¼Ì³ÐµÄ¹ØÏµÇå³þһЩ£¨¸ÃͼƬÀ´×ÔÕâÀ

¸ÃͼÖУ¬×îÈÃÈËÀ§»óµÄιýÓÚRoot ClassÁË¡£ÔÚʵÏÖÖУ¬Root ClassÊÇÖ¸NSObject£¬ÎÒÃÇ¿ÉÒÔ´ÓͼÖп´³ö£º
NSObjectÀà°üÀ¨ËüµÄ¶ÔÏóʵÀý·½·¨¡£
NSObjectµÄÔªÀà°üÀ¨ËüµÄÀà·½·¨£¬ÀýÈçalloc·½·¨¡£
NSObjectµÄÔªÀà¼Ì³Ð×ÔNSObjectÀà¡£
Ò»¸öNSObjectµÄÀàÖеķ½·¨Í¬Ê±Ò²»á±»NSObjectµÄ×ÓÀàÔÚ²éÕÒ·½·¨Ê±ÕÒµ½¡£
ÀàµÄ³ÉÔ±±äÁ¿
Èç¹û°ÑÀàµÄʵÀý¿´³ÉÒ»¸öCÓïÑԵĽṹÌ壨struct£©£¬ÉÏÃæËµµÄisaÖ¸Õë¾ÍÊÇÕâ¸ö½á¹¹ÌåµÄµÚÒ»¸ö³ÉÔ±±äÁ¿£¬¶øÀàµÄÆäËü³ÉÔ±±äÁ¿ÒÀ´ÎÅÅÁÐÔڽṹÌåÖС£ÅÅÁÐ˳ÐòÈçÏÂͼËùʾ£¨Í¼Æ¬À´×Ô¡¶iOS
6 Programming Pushing the Limits¡·£©£º

ΪÁËÑéÖ¤¸Ã˵·¨£¬ÎÒÃÇÔÚXCodeÖÐн¨Ò»¸ö¹¤³Ì£¬ÔÚmain.mÖÐÔËÐÐÈçÏ´úÂ룺
import
@interface Father : NSObject {
int _father;
}
@end
@implementation Father
@end
@interface Child : Father {
int _child;
}
@end
@implementation Child
@end
int main(int argc, char * argv[])
{
Child * child = [[Child alloc] init];
@autoreleasepool {
// ...
}
}
|
ÎÒÃǽ«¶ÏµãÏÂÔÚ @autoreleasepool ´¦£¬È»ºóÔÚConsoleÖÐÊäÈëp *child,Ôò¿ÉÒÔ¿´µ½XcodeÊä³öÈçÏÂÄÚÈÝ£¬ÕâÓëÎÒÃÇÉÏÃæµÄ˵·¨Ò»Ö¡£
(lldb) p *child
(Child) $0 = {
(Father) Father = {
(NSObject) NSObject = {
(Class) isa = Child
}
(int) _father = 0
}
(int) _child = 0
}
|
¿É±äÓë²»¿É±ä
ÒòΪ¶ÔÏóÔÚÄÚ´æÖеÄÅŲ¼¿ÉÒÔ¿´³ÉÒ»¸ö½á¹¹Ì壬¸Ã½á¹¹ÌåµÄ´óС²¢²»Äܶ¯Ì¬±ä»¯¡£ËùÒÔÎÞ·¨ÔÚÔËÐÐʱ¶¯Ì¬¸ø¶ÔÏóÔö¼Ó³ÉÔ±±äÁ¿¡£
Ïà¶ÔµÄ£¬¶ÔÏóµÄ·½·¨¶¨Òå¶¼±£´æÔÚÀàµÄ¿É±äÇøÓòÖС£Objective-C 2.0²¢Î´ÔÚÍ·ÎļþÖн«ÊµÏÖ±©Â¶³öÀ´£¬µ«ÔÚObjective-C
1.0ÖУ¬ÎÒÃÇ¿ÉÒÔ¿´µ½·½·¨µÄ¶¨ÒåÁбíÊÇÒ»¸öÃûΪ methodListsµÄÖ¸ÕëµÄÖ¸Õ루ÈçÏÂͼËùʾ£©¡£Í¨¹ýÐ޸ĸÃÖ¸ÕëÖ¸ÏòµÄÖ¸ÕëµÄÖµ£¬¾Í¿ÉÒÔʵÏÖ¶¯Ì¬µØÎªÄ³Ò»¸öÀàÔö¼Ó³ÉÔ±·½·¨¡£ÕâÒ²ÊÇCategoryʵÏÖµÄÔÀí¡£Í¬Ê±Ò²ËµÃ÷ÁËΪʲôCategoryÖ»¿ÉΪ¶ÔÏóÔö¼Ó³ÉÔ±·½·¨£¬È´²»ÄÜÔö¼Ó³ÉÔ±±äÁ¿¡£

ÐèÒªÌØ±ð˵Ã÷һϣ¬Í¨¹ýobjc_setAssociatedObject ºÍ objc_getAssociatedObject·½·¨¿ÉÒÔ±äÏàµØ¸ø¶ÔÏóÔö¼Ó³ÉÔ±±äÁ¿£¬µ«ÓÉÓÚʵÏÖ»úÖÆ²»Ò»Ñù£¬ËùÒÔ²¢²»ÊÇÕæÕý¸Ä±äÁ˶ÔÏóµÄÄÚ´æ½á¹¹¡£
³ýÁ˶ÔÏóµÄ·½·¨¿ÉÒÔ¶¯Ì¬Ð޸ģ¬ÒòΪisa±¾ÉíÒ²Ö»ÊÇÒ»¸öÖ¸Õ룬ËùÒÔÎÒÃÇÒ²¿ÉÒÔÔÚÔËÐÐʱ¶¯Ì¬µØÐÞ¸ÄisaÖ¸ÕëµÄÖµ£¬´ïµ½Ìæ»»¶ÔÏóÕû¸öÐÐΪµÄÄ¿µÄ¡£²»¹ý¸ÃÓ¦Óó¡¾°½ÏÉÙ¡£
ϵͳÏà¹ØAPI¼°Ó¦ÓÃ
isa swizzlingµÄÓ¦ÓÃ
ϵͳÌṩµÄKVOµÄʵÏÖ£¬¾ÍÀûÓÃÁ˶¯Ì¬µØÐÞ¸ÄisaÖ¸ÕëµÄÖµµÄ¼¼Êõ¡£ÔÚÆ»¹ûµÄÎĵµÖпÉÒÔ¿´µ½ÈçÏÂÃèÊö£º
Key-Value Observing Implementation Details
Automatic key-value observing is implemented using a technique called isa-swizzling.
The isa pointer, as the name suggests, points to the object¡¯s class which maintains a dispatch table.
This dispatch table essentially contains pointers to the methods the class implements, among other data.
When an observer is registered for an attribute of an object the isa pointer of the observed object is modified,
pointing to an intermediate class rather than at the true class.
As a result the value of the isa pointer does not necessarily reflect the actual class of the instance.
You should never rely on the isa pointer to determine class membership.
Instead, you should use the class method to determine the class of an object instance.
|
ÀàËÆµÄ£¬Ê¹ÓÃisa swizzlingµÄ¼¼ÊõµÄ»¹ÓÐϵͳÌṩµÄKey-Value Coding£¨KVC£©¡£
(лл´ó¼ÒÖ¸³ö´íÎó£¬KVC²¢Ã»ÓÐʹÓõ½isa swizzling)
Method Swizzling API˵Ã÷
Objective-CÌṩÁËÒÔÏÂAPIÀ´¶¯Ì¬Ìæ»»Àà·½·¨»òʵÀý·½·¨µÄʵÏÖ£º
1.class_replaceMethod Ìæ»»Àà·½·¨µÄ¶¨Òå
2.method_exchangeImplementations ½»»»2¸ö·½·¨µÄʵÏÖ
3.method_setImplementation ÉèÖÃ1¸ö·½·¨µÄʵÏÖ
Õâ3¸ö·½·¨ÓÐһЩϸ΢µÄ²î±ð£¬¸ø´ó¼Ò½éÉÜÈçÏ£º
class_replaceMethodÔÚÆ»¹ûµÄÎĵµ£¨ÈçÏÂͼËùʾ£©ÖÐÄÜ¿´µ½£¬ËüÓÐÁ½ÖÖ²»Í¬µÄÐÐΪ¡£µ±ÀàÖÐûÓÐÏëÌæ»»µÄÔ·½·¨Ê±£¬¸Ã·½·¨»áµ÷ÓÃclass_addMethodÀ´Îª¸ÃÀàÔö¼ÓÒ»¸öз½·¨£¬Ò²ÒòΪÈç´Ë£¬class_replaceMethodÔÚµ÷ÓÃʱÐèÒª´«Èëtypes²ÎÊý£¬¶ømethod_exchangeImplementationsºÍmethod_setImplementationÈ´²»ÐèÒª¡£

method_exchangeImplementations µÄÄÚ²¿ÊµÏÖÏ൱ÓÚµ÷ÓÃÁË2´Îmethod_setImplementation·½·¨£¬´ÓÆ»¹ûµÄÎĵµÖÐÄÜÇåÎúµØÁ˽⵽£¨ÈçÏÂͼËùʾ£©

´ÓÒÔÉϵÄÇø±ðÎÒÃÇ¿ÉÒÔ×ܽá³öÕâ3¸öAPIµÄʹÓó¡¾°:
1.class_replaceMethod, µ±ÐèÒªÌæ»»µÄ·½·¨¿ÉÄÜÓв»´æÔÚµÄÇé¿öʱ£¬¿ÉÒÔ¿¼ÂÇʹÓø÷½·¨¡£
2.method_exchangeImplementations£¬µ±ÐèÒª½»»»2¸ö·½·¨µÄʵÏÖʱʹÓá£
3.method_setImplementation ×î¼òµ¥µÄÓ÷¨£¬µ±½ö½öÐèҪΪһ¸ö·½·¨ÉèÖÃÆäʵÏÖ·½Ê½Ê±Ê¹Óá£
ÒÔÉÏ3¸ö·½·¨µÄÔ´ÂëÔÚÕâÀ¸ÐÐËȤµÄͬѧ¿ÉÒÔ¶ÁÒ»¶Á¡£
ʹÓÃʾÀý
ÎÒÃÇÔÚ¿ª·¢Ô³Ìâ¿â¿Í»§¶ËµÄ±Ê¼Ç¹¦ÄÜʱ£¬ÐèҪʹÓÃϵͳµÄUIImagePickerController¡£µ«ÊÇ£¬ÎÒÃÇ·¢ÏÖ£¬ÔÚiOS6.0.2ϵͳÏ£¬ÏµÍ³ÌṩµÄUIImagePickerControllerÔÚiPadºáÆÁÏÂÓÐתÆÁµÄBug£¬Ôì³ÉÆä·½Ïò´íÎó¡£¾ßÌåµÄBugÏêÇé¿ÉÒÔ¼ûÕâÀï¡£
ΪÁËÐÞ¸´¸ÃBug£¬ÎÒÃÇÐèÒªÌæ»»UIImagePickerControllerµÄÈçÏÂ2¸ö·½·¨
- (BOOL)shouldAutorotate; - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation; |
ÎÒÃÇÏÈʵÏÖÁËÒ»¸öÃûΪImagePickerReplaceMethodsHolderµÄÀ࣬ÓÃÓÚ¶¨ÒåÌæ»»ºóµÄ·½·¨ºÍʵÏÖ¡£ÈçÏÂËùʾ£º
/ ImagePickerReplaceMethodsHolder.h
@interface ImagePickerReplaceMethodsHolder : NSObject
- (BOOL)shouldAutorotate;
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;
@end
// ImagePickerReplaceMethodsHolder.m
@implementation ImagePickerReplaceMethodsHolder
- (BOOL)shouldAutorotate {
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
@end
|
È»ºó£¬ÎÒÃÇÔÚµ÷Óô¦£¬Åжϵ±Ç°µÄiOS°æ±¾£¬¶ÔÓÚ[iOS6.0, iOS6.1)Ö®¼äµÄ°æ±¾£¬ÎÒÃǽ«UIImagePickerControllerµÄÓÐÎÊÌâµÄ·½·¨Ìæ»»¡£¾ßÌå´úÂëÈçÏ£º
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)
([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)
([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self hackForImagePicker];
});
}
+ (void)hackForImagePicker {
// fix bug of image picker under iOS 6.0
// http://stackoverflow.com/questions/12522491/crash-on-presenting-uiimagepickercontroller-under-ios-6-0
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")
&& SYSTEM_VERSION_LESS_THAN(@"6.1")) {
Method oldMethod1 = class_getInstanceMethod([UIImagePickerController class], @selector(shouldAutorotate));
Method newMethod1 = class_getInstanceMethod([ImagePickerReplaceMethodsHolder class], @selector(shouldAutorotate));
method_setImplementation(oldMethod1, method_getImplementation(newMethod1));
Method oldMethod2 = class_getInstanceMethod([UIImagePickerController class],
@selector(preferredInterfaceOrientationForPresentation));
Method newMethod2 = class_getInstanceMethod([ImagePickerReplaceMethodsHolder class],
@selector(preferredInterfaceOrientationForPresentation));
method_setImplementation(oldMethod2, method_getImplementation(newMethod2));
}
}
|
ͨ¹ýÈçÉÏ´úÂ룬ÎÒÃǾÍÕë¶ÔiOSÌØ¶¨°æ±¾µÄÓÐÎÊÌâµÄϵͳ¿âº¯Êý´òÁËPatch£¬Ê¹ÎÊÌâµÃµ½½â¾ö¡£
¿ªÔ´½çµÄʹÓÃ
ÓÐÉÙÁ¿²»Ã÷ÕæÏàµÄͬѧÒÔΪƻ¹ûÔÚÉóºËʱ»á¾Ü¾øAppʹÓÃÒÔÉÏAPI£¬ÕâÆäʵÊÇ¶ÔÆ»¹ûµÄÎó½â¡£Ê¹ÓÃÈçÉÏAPIÊǰ²È«µÄ¡£ÁíÍ⣬¿ªÔ´½çÒ²¶ÔÒÔÉÏ·½·¨¶¼Êʵ±µÄʹÓá£ÀýÈ磺
ÖøÃûµÄÍøÂç¿âAFNetworking¡£AFNetworkingÍøÂç¿â(v1.x°æ±¾)ʹÓÃÁËclass_replaceMethod·½·¨£¨AFHTTPRequestOperation.mÎļþµÚ105ÐУ©
Nimbus¡£NimbusÊÇÖøÃûµÄ¹¤¾ßÀà¿â£¬ËüÔÚÆäcoreÄ£¿éÖÐÌṩÁËNIRuntimeClassModifications.hÎļþ£¬ÓÃÓÚÌṩÉÏÊöAPIµÄ·â×°¡£
¹úÄڵĴóÖÚµãÆÀiOS¿Í»§¶Ë¡£¸Ã¿Í»§¶ËʹÓÃÁËËûÃÇ×Ô¼º¿ª·¢µÄ»ùÓÚWaxÐ޸ĶøÀ´µÄWaxPatch£¬WaxPatch¿ÉÒÔʵÏÖͨ¹ý·þÎñÆ÷¸üÐÂÀ´¶¯Ì¬Ð޸Ŀͻ§¶ËµÄÂß¼¡£¶øWaxPatchÖ÷ÒªÊÇÐÞ¸ÄÁËwaxÖеÄwax_instance.mÎļþ£¬ÔÚÆäÖмÓÈëÁËclass_replaceMethodÀ´Ìæ»»ÔʼʵÏÖ£¬´Ó¶øÊµÏÖÐ޸Ŀͻ§¶ËµÄÔÓÐÐÐΪ¡£
×ܽá
ͨ¹ý±¾ÎÄ£¬ÎÒÃÇÁ˽⵽ÁËObjective-CÓïÑԵĶÔÏóÄ£ÐÍ£¬ÒÔ¼°Objective-CÓïÑÔ¶ÔÏóÄ£ÐÍÖжÔisa
swizzlingºÍmethod swizzlingµÄÖ§³Ö¡£±¾ÎÄҲͨ¹ý¾ßÌåµÄʵÀý´úÂëºÍ¿ªÔ´ÏîÄ¿£¬ÈÃÎÒÃǶԸöÔÏóÄ£ÐÍÌṩµÄ¶¯Ì¬ÐÔÓÐÁ˸ü¼ÓÉî¿ÌµÄÈÏʶ¡£ |