Objective-C runtimeÖ®ÔËÐÐʱµÄ»ù±¾Ìص㣨һ£©
×÷ΪһÃŶ¯Ì¬±à³ÌÓïÑÔ£¬Objective-C »á¾¡¿ÉÄܵĽ«±àÒëºÍÁ´½ÓʱҪ×öµÄÊÂÇéÍÆ³Ùµ½ÔËÐÐʱ¡£Ö»ÒªÓпÉÄÜ,Objective-C
×ÜÊÇʹÓö¯Ì¬ µÄ·½Ê½À´½â¾öÎÊÌâ¡£ÕâÒâζ×Å Objective-C ÓïÑÔ²»½öÐèÒªÒ»¸ö±àÒë»·¾³,ͬʱҲÐèÒªÒ»¸öÔËÐÐʱϵͳÀ´Ö´ÐбàÒëºÃµÄ´úÂë¡£ÔËÐÐʱϵͳ£¨runtime£©°çÑݵĽÇÉ«ÀàËÆÓÚ
Objective-C ÓïÑԵIJÙ×÷ϵͳ,Objective-C »ùÓÚ¸ÃϵͳÀ´¹¤×÷¡£Òò´Ë£¬runtimeºÃ±ÈObjective-CµÄÁé»ê,ºÜ¶à¶«Î÷¶¼ÊÇÔÚÕâ¸ö»ù´¡ÉϳöÏֵġ£ËùÒÔËüÊÇÖµµÄÄ㻨¹¦·òÈ¥Àí½âµÄ¡£
ÎÒÃǽ«´ÓÒÔϼ¸¸ö·½ÃæÁ˽âObjective-CµÄÔËÐÐʱ£º
Ò»¡¢Ó뾲̬ÓïÑÔ±àÒëºóµÄÇø±ð
1¡¢¾²Ì¬ÓïÑÔ
Ò»¸ö¾²Ì¬ÓïÑÔ³ÌÐò£¬ÈçÏÂËùʾµÄC³ÌÐò£º
#include < stdio.h > int main(int argc, const char **argv[]) { printf("Hello World!"); return 0; } |
»á¾¹ý±àÒëÆ÷µÄÓï·¨·ÖÎö£¬ÓÅ»¯È»ºó½«Äã×î¼Ñ»¯µÄ´úÂë·Òë³É»ã±àÓïÑÔ£¬È»ºóÍêÈ«°´ÕÕÄãÉè¼ÆµÄÂß¼ºÍÄãµÄ´úÂë×ÔÉ϶øÏµÄÖ´ÐС£
2¡¢Objective-C
ºÜ³£¼ûµÄÒ»¸öÏûÏ¢·¢ËÍÓï¾ä£º
»á±»±àÒëÆ÷ת»¯³É
objc_msgSend(receiver, selector) |
Èç¹ûÓвÎÊýÔòΪ
objc_msgSend(receiver, selector, arg1, arg2, ¡) |
ÏûÏ¢Ö»Óе½ÔËÐÐʱ²Å»áºÍº¯ÊýʵÏְ󶍯ðÀ´£¬¶ø²»Êǰ´ÕÕ±àÒëºÃµÄÂß¼Ò»³É²»±äµÄÖ´ÐС£°´ÕÕÎÒµÄÀí½â£¬±àÒë½×¶ÎÖ»ÊÇÈ·¶¨ÁËҪȥÏòreceiver¶ÔÏó·¢ËÍmessageÏûÏ¢£¬µ«ÊÇȴûÓз¢ËÍ£¬ÕæÕý·¢ËÍÊǵȵ½ÔËÐеÄʱºò½øÐС£Òò´Ë£¬±àÒë½×¶ÎÍêÈ«²»ÖªµÀmessage·½·¨µÄ¾ßÌåʵÏÖ£¬ÉõÖÁ£¬¸Ã·½·¨µ½µ×ÓÐûÓб»ÊµÏÖÒ²²»ÖªµÀ¡£Õâ¾ÍÓпÉÄܵ¼ÖÂÔËÐÐʱ±ÀÀ£ÎÊÌâ¡£
¶þ¡¢Objective-c runtimeµÄ¼¸µã˵Ã÷
1¡¢runtimeÊÇ¿ªÔ´µÄ
Êǵģ¬Äãû¿´´í£¬runtimeȷʵÊÇ¿ªÔ´µÄ¡£Ä¿Ç°Æ»¹û¹«Ë¾ºÍGNU¸÷×Ôά»¤Ò»¸ö¿ªÔ´µÄruntime°æ±¾£¬ÕâÁ½¸ö°æ±¾Ö®¼ä¶¼ÔÚŬÁ¦µÄ±£³ÖÒ»Ö¡£ÆäÖÐÆ»¹ûµÄ°æ±¾¿ÉÒÔÃÍ»÷¸ÃÁ´½ÓÏÂÔØobjc4-437.1.tar.gz
2¡¢runtimeÊÇÓÉCÓïÑÔʵÏÖµÄ
runtime×öΪObjective-C×îºËÐĵIJ¿·Ö£¬¼¸ºõÈ«²¿ÓÉCÓïÑÔʵÏÖ¡£ÕâÀïµÄ¡°¼¸ºõ¡±ËùÖ¸µÄÀýÍâ¾Í°üº¬Óеķ½·¨£¨±ÈÈçÏÂÃæÒªËµµÀµÄobjc_msgSend·½·¨£©ÉõÖÁÊÇÓûã±àʵÏֵģ¡£¡
3¡¢runtimeµÄÁ½¸ö°æ±¾
Objective-CÔËÐÐʱϵͳÓÐÁ½¸öÒÑÖª°æ±¾:ÔçÆÚ°æ±¾£¨Legacy£©ºÍÏÖÐа汾£¨Modern£©¡£
ÔÚÏÖÐа汾ÖÐ,×îÏÔÖøµÄÐÂÌØÐÔ¾ÍÊÇʵÀý±äÁ¿ÊÇ"½¡×³¡°(non-fragile)µÄ:
ÔÚÔçÆÚ°æ±¾ÖÐ,Èç¹ûÄú¸Ä±äÀàÖÐʵÀý±äÁ¿µÄ²¼¾Ö,Äú±ØÐëÖØÐ±àÒë¸ÃÀàµÄËùÓÐ×ÓÀà¡£
ÔÚÏÖÐа汾ÖÐ,Èç¹ûÄú¸Ä±äÀàÖÐʵÀý±äÁ¿µÄ²¼¾Ö,ÄúÎÞÐèÖØÐ±àÒë¸ÃÀàµÄÈκÎ×ÓÀà¡£
´ËÍâ,ÏÖÐа汾֧³ÖÉùÃ÷propertyµÄsynthesisÊôÐÔÆ÷¡£
ĿǰiPhone ³ÌÐòºÍ Mac OS X v10.5 ¼°ÒÔºóµÄϵͳÖеÄ
64 λ³ÌÐòʹÓõͼÊÇ Objective-C ÔËÐÐʱϵͳµÄÏÖÐÐ°æ ±¾¡£ÆäËüÇé¿ö(Mac OS X ϵͳÖеÄ
32 λ³ÌÐò)ʹÓõÄÊÇÔçÆÚ°æ±¾¡£
Èý¡¢ºÍruntime system½»»¥µÄÈýÖÖ·½Ê½
1¡¢Í¨¹ýObjective-CÔ´´úÂë
´ó²¿·ÖÇé¿öÏÂ,ÔËÐÐʱϵͳÔÚºǫ́×Ô¶¯ÔËÐÐ,ÎÒÃÇÖ»Ðè±àдºÍ±àÒë Objective-C
Ô´´úÂë¡£
µ±±àÒëObjective-CÀàºÍ·½·¨Ê±,±àÒëÆ÷ΪʵÏÖÓïÑÔ¶¯Ì¬ÌØÐÔ½«×Ô¶¯´´½¨Ò»Ð©Êý¾Ý½á¹¹ºÍº¯Êý¡£ÕâЩÊý¾Ý
½á¹¹°üº¬ÀඨÒåºÍÐÒéÀඨÒåÖеÄÐÅÏ¢,ÈçÔÚObjective-C 2.0 ³ÌÐòÉè¼ÆÓïÑÔÖж¨ÒåÀàºÍÐÒéÀàÒ»½ÚËùÌÖÂÛ
µÄÀàµÄ¶ÔÏóºÍÐÒéÀàµÄ¶ÔÏó,·½·¨Ñ¡±ê,ʵÀý±äÁ¿Ä£°å,ÒÔ¼°ÆäËüÀ´×ÔÓÚÔ´´úÂëµÄÐÅÏ¢¡£ÔËÐÐʱϵͳµÄÖ÷Òª¹¦ÄܾÍÊǸù¾ÝÔ´´úÂëÖеıí´ïʽ·¢ËÍÏûÏ¢¡£
2¡¢Í¨¹ýÀàNSObjectµÄ·½·¨
Cocoa³ÌÐòÖоø´ó²¿·ÖÀà¶¼ÊÇNSObjectÀàµÄ×ÓÀà,ËùÒԴ󲿷ֶ¼¼Ì³ÐÁËNSObjectÀàµÄ·½·¨,Òò¶ø¼Ì³Ð
ÁËNSObjectµÄÐÐΪ(NSProxyÀàÊǸöÀýÍâ)¡£È»¶ø,ijЩÇé¿öÏÂ, NSObjectÀà½ö½ö¶¨ÒåÁËÍê³Éij¼þÊÂÇéµÄÄ£°å,¶øÃ»ÓÐÌṩËùÓÐÐèÒªµÄ´úÂë¡£
ÀýÈç,NSObject ÀඨÒåÁËdescription·½·¨,·µ»Ø¸ÃÀàÄÚÈݵÄ×Ö·û´®±íʾ¡£ÕâÖ÷ÒªÊÇÓÃÀ´µ÷ÊÔ³ÌÐò
¡ª¡ªGDB ÖÐµÄ print-object ·½·¨¾ÍÊÇÖ±½Ó´òÓ¡³ö¸Ã·½·¨·µ»ØµÄ×Ö·û´®¡£NSObject ÀàÖи÷½·¨µÄ
ʵÏÖ²¢²»ÖªµÀ×ÓÀàÖеÄÄÚÈÝ,ËùÒÔËüÖ»ÊÇ·µ»ØÀàµÄÃû×ֺͶÔÏóµÄµØÖ·¡£NSObject µÄ×ÓÀà¿ÉÒÔÖØÐÂʵÏָ÷½·¨ÒÔÌṩ¸ü¶àµÄÐÅÏ¢¡£ÀýÈç,NSArray
Àà¸ÄдÁ˸÷½·¨À´·µ»Ø NSArray Àà°üº¬µÄÿ¸ö¶ÔÏóµÄÄÚÈÝ¡£
ijЩ NSObject µÄ·½·¨Ö»ÊǼòµ¥µØ´ÓÔËÐÐʱϵͳÖлñµÃÐÅÏ¢,´Ó¶øÔÊÐí¶ÔÏó½øÐÐÒ»¶¨³Ì¶ÈµÄ×ÔÎÒ¼ì²é¡£
ÀýÈç,class ·µ»Ø¶ÔÏóµÄÀà;isKindOfClass:ºÍ isMemberOfClass:Ôò¼ì²é¶ÔÏóÊÇ·ñÔÚÖ¸¶¨µÄ
Àà¼Ì³ÐÌåϵÖÐ;respondsToSelector:¼ì²é¶ÔÏóÄÜ·ñÏìÓ¦Ö¸¶¨µÄÏûÏ¢;conformsToProtocol:
¼ì²é¶ÔÏóÊÇ·ñʵÏÖÁËÖ¸¶¨ÐÒéÀàµÄ·½·¨;methodForSelector:Ôò·µ»ØÖ¸¶¨·½·¨ÊµÏֵĵØÖ·¡£
3¡¢Í¨¹ýÔËÐÐʱϵͳµÄº¯Êý
ÔËÐÐʱϵͳÊÇÒ»¸öÓй«¿ª½Ó¿ÚµÄ¶¯Ì¬¿â,ÓÉһЩÊý¾Ý½á¹¹ºÍº¯ÊýµÄ¼¯ºÏ×é³É,ÕâЩÊý¾Ý½á¹¹ºÍº¯ÊýµÄÉùÃ÷ Í·ÎļþÔÚ/usr/include/objcÖС£ÕâЩº¯ÊýÖ§³ÖÓô¿CµÄº¯ÊýÀ´ÊµÏÖºÍObjective-CͬÑùµÄ¹¦ÄÜ¡£»¹ÓÐһЩº¯Êý¹¹³ÉÁË
NSObject Àà·½·¨µÄ»ù´¡¡£ÕâЩº¯ÊýʹµÃ·ÃÎÊÔËÐÐʱϵͳ½Ó¿ÚºÍÌṩ¿ª·¢¹¤¾ß³ÉΪ¿É ÄÜ¡£¾¡¹Ü´ó²¿·ÖÇé¿öÏÂËüÃÇÔÚ
Objective-C ³ÌÐò²»ÊDZØÐëµÄ,µ«ÊÇÓÐʱºò¶ÔÓÚ Objecitve-C ³ÌÐòÀ´ËµÄ³Ð©º¯ ÊýÊǷdz£ÓÐÓõġ£
ÕâЩº¯ÊýµÄÎĵµ²Î¼û Objective-C 2.0 ÔËÐÐʱϵͳ²Î¿¼¿â¡£
Objective-C runtimeÖ®ÏûÏ¢£¨¶þ£©
½ñÌ쿪ʼ˵˵runtime systemÖÐ×î¹Ø¼üµÄÏûÏ¢Ïà¹ØÄÚÈÝ¡£
Ò»¡¢runtimeÖеÄÏûÏ¢
1¡¢Ê²Ã´ÊÇÏûÏ¢
½øÈë½ñÌìµÄÕýÌâ֮ǰ£¬ÏÈÀ´ËµËµ¸úmessageϢϢÏà¹ØµÄ¼¸¸ö¸ÅÄî
¢Ùmessage£¨ÏûÏ¢£©
messageµÄ¾ßÌ嶨ÒåºÜÄÑ˵£¬ÒòΪ²¢Ã»ÓÐÕæÕýµÄ´úÂëÃèÊö£¬¼òµ¥µÄ½²message
ÊÇÒ»ÖÖ³éÏ󣬰üÀ¨Á˺¯ÊýÃû+²ÎÊýÁÐ±í£¬Ëû²¢Ã»ÓÐʵ¼ÊµÄʵÌå´æÔÚ¡£
¢Úmethod£¨·½·¨£©
methodÊÇÕæÕýµÄ´æÔڵĴúÂë¡£È磺- (int)meaning { return
42; }
¢Ûselector£¨·½·¨Ñ¡ÔñÆ÷£©
selector ͨ¹ýSELÀàÐÍ´æÔÚ£¬ÃèÊöÒ»¸öÌØ¶¨µÄmethod »òÕß˵
message¡£ÔÚʵ¼Ê±à³ÌÖУ¬¿ÉÒÔͨ¹ýselector½øÐмìË÷·½·¨µÈ²Ù×÷¡£
2¡¢Á½¸ö¸úÏûÏ¢Ïà¹ØµÄ¸ÅÄî
¢ÙSEL
SELÓֽз½·¨Ñ¡ÔñÆ÷£¬Õâµ½µ×ÊǸöÊ²Ã´ÍæÒâÄØ£¿ÔÚobjc.hÖÐÊÇÕâÑù¶¨ÒåµÄ£º
typedef struct objc_selector *SEL; |
Õâ¸öSEL±íʾʲô£¿Ê×ÏÈ£¬Ëµ°×ÁË£¬·½·¨Ñ¡ÔñÆ÷½ö½öÊÇÒ»¸öchar *Ö¸Õ룬½ö½ö±íʾËüËù´ú±íµÄ·½·¨Ãû×Ö°ÕÁË£¬ÓÐÈçÏÂÖ¤¾Ý£º
SEL selector = @selector(message); //@selector²»ÊǺ¯Êýµ÷Óã¬Ö»ÊǸøÕâ¸ö¿ÓµùµÄ±àÒëÆ÷µÄÒ»¸öÌáʾ NSLog (@"%s", (char *)selector); //print message |
Õâʱ´òÓ¡µÄ½á¹û¾ÍÊÇ£ºmessage
Objective-CÔÚ±àÒëµÄʱºò£¬»á¸ù¾Ý·½·¨µÄÃû×Ö£¬Éú³ÉÒ»¸öÓà À´Çø·ÖÕâ¸ö·½·¨µÄΨһµÄÒ»¸öID£¬Õâ¸öID¾ÍÊÇSELÀàÐ͵ġ£ÎÒÃÇÐèҪעÒâµÄÊÇ£¬Ö»Òª·½·¨µÄÃû×ÖÏàͬ£¬ÄÇôËüÃǵÄID¶¼ÊÇÏàͬµÄ¡£¾ÍÊÇ˵£¬²»¹ÜÊdz¬À໹ÊÇ×ÓÀ࣬²»¹ÜÊÇÓÐûÓг¬ÀàºÍ×ÓÀàµÄ¹ØÏµ£¬Ö»ÒªÃû×ÖÏàͬÄÇôID¾ÍÊÇÒ»ÑùµÄ¡£
¶øÕâÒ²¾Íµ¼ÖÂÁËObjective-CÔÚ´¦ÀíÓÐÏàͬº¯ÊýÃûºÍ²ÎÊý¸öÊýµ«²ÎÊýÀàÐͲ»Í¬µÄº¯ÊýµÄÄÜÁ¦·Ç³£µÄÈõ£¬±ÈÈçµ±ÄãÏëÔÚ³ÌÐòÖÐʵÏÖÏÂÃæÁ½¸ö·½·¨£º
-(void)setWidth:(int)width£» -(void)setWidth:(double)width£» |
ÕâÑùµÄº¯ÊýÔò±»ÈÏΪÊÇÒ»ÖÖ±àÒë´íÎ󣬶øÕâ×îÖÕµ¼ÖÂÁËÒ»¸ö·Ç³£·Ç³£Ææ¹ÖµÄObjective-CÌØÉ«µÄº¯ÊýÃüÃû£º
-(void)setWidthIntValue:(int)width£» -(void)setWidthDoubleValue:(double)width£» |
¿ÉÄÜÓÐÈË»áÎÊ£¬runtime·ÑÁËÄÇôÀϰëÌì¾¢£¬¾¿¾¹Ïë×öʲô£¿GCÀ´ÁË¡£
¸Õ²ÅÎÒÃÇ˵µÀ£¬±àÒëÆ÷»á¸ù¾Ýÿ¸ö·½·¨µÄ·½·¨ÃûΪÄǸö·½·¨Éú³ÉΨһµÄSEL£¬ÕâЩSEL×é³ÉÁËÒ»¸öSet¼¯ºÏ£¬Õâ¸öSet¼òµ¥µÄ˵¾ÍÊÇÒ»¸ö¾¹ýÁËÓÅ»¯¹ýµÄhash±í¡£¶øSetµÄÌØµã¾ÍÊÇΨһ£¬Ò²¾ÍÊÇSELÊÇΨһµÄ£¬Òò´Ë£¬Èç¹ûÎÒÃÇÏëµ½Õâ¸ö·½·¨¼¯ºÏÖвéÕÒij¸ö·½·¨Ê±£¬Ö»ÐèҪȥÕÒµ½Õâ¸ö·½·¨¶ÔÓ¦µÄSEL¾ÍÐÐÁË£¬SELʵ¼ÊÉϾÍÊǸù¾Ý·½·¨Ãûhash»¯Á˵ÄÒ»¸ö×Ö·û´®£¬¶ø¶ÔÓÚ×Ö·û´®µÄ±È½Ï½ö½öÐèÒª±È½ÏËûÃǵĵØÖ·¾Í¿ÉÒÔÁË£¬Ï¬Àû£¬ËÙ¶ÈÉÏÎÞÓïÂױȣ¡£¡µ«ÊÇ£¬ÓÐÒ»¸öÎÊÌ⣬¾ÍÊÇÊýÁ¿Ôö¶à»áÔö´óhash³åÍ»¶øµ¼ÖµÄÐÔÄÜϽµ£¨»òÊÇûÓгåÍ»£¬ÒòΪҲ¿ÉÄÜÓõÄÊÇperfect
hash£©¡£µ«ÊDz»¹ÜʹÓÃʲôÑùµÄ·½·¨¼ÓËÙ£¬Èç¹ûÄܹ»½«×ÜÁ¿¼õÉÙ£¨¶à¸ö·½·¨¿ÉÄܶÔӦͬһ¸öSEL£©£¬Äǽ«ÊÇ×îϬÀûµÄ·½·¨¡£ÄÇô£¬ÎÒÃǾͲ»ÄÑÀí½â£¬ÎªÊ²Ã´SEL½ö½öÊǺ¯ÊýÃûÁË¡£
µ½ÕâÀÎÒÃÇÃ÷°×ÁË£¬±¾ÖÊÉÏ£¬SELÖ»ÊÇÒ»¸öÖ¸Ïò·½·¨µÄÖ¸Õ루׼ȷµÄ˵£¬Ö»ÊÇÒ»¸ö¸ù¾Ý·½·¨Ãûhash»¯Á˵ÄKEYÖµ£¬ÄÜΨһ´ú±íÒ»¸ö·½·¨£©£¬ËüµÄ´æÔÚÖ»ÊÇΪÁ˼ӿ췽·¨µÄ²éѯËÙ¶È£¡£¡£¡£¡
¢ÚIMP
IMPÔÚobjc.hÖÐÊÇÈç´Ë¶¨ÒåµÄ£º
typedef id (*IMP)(id, SEL, ...); |
Õâ¸ö±ÈSELÒªºÃÀí½â¶àÁË£¬ÊìϤCÓïÑÔµÄͬѧ¶¼ÖªµÀ£¬ÕâÆäʵÊÇÒ»¸öº¯ÊýÖ¸Õë¡£Ç°Ãæ½éÉܹýµÄSEL£¬¾ÍÊÇΪIMP·þÎñµÄ¡£ÓÉÓÚÿ¸ö·½·¨¶¼¶ÔӦΨһµÄSEL£¬Òò´ËÎÒÃÇ¿ÉÒÔͨ¹ýSEL·½±ã¡¢¿ìËÙ¡¢×¼È·µÄ»ñµÃËüËù¶ÔÓ¦µÄIMP£¨Ò²¾ÍÊǺ¯ÊýÖ¸Õ룩£¬¶øÔÚÈ¡µÃÁ˺¯ÊýÖ¸ÕëÖ®ºó£¬Ò²¾ÍÒâζ×ÅÎÒÃÇÈ¡µÃÁËÖ´ÐеÄʱºòµÄÕâ¶Î·½·¨µÄ´úÂëµÄÈë¿Ú£¬ÕâÑùÎÒÃǾͿÉÒÔÏñÆÕͨµÄCÓïÑÔº¯Êýµ÷ÓÃÒ»ÑùʹÓÃÕâ¸öº¯ÊýÖ¸Õë¡£µ±È»ÎÒÃÇ¿ÉÒ԰Ѻ¯ÊýÖ¸Õë×÷Ϊ²ÎÊý´«µÝµ½ÆäËûµÄ·½·¨£¬»òÕßʵÀý±äÁ¿ÀïÃæ£¬´Ó¶ø»ñµÃ¼«´óµÄ¶¯Ì¬ÐÔ¡£
ÏÂÃæµÄÀý×Ó£¬½éÉÜÁËÈ¡µÃº¯ÊýÖ¸Õ룬¼´º¯ÊýÖ¸ÕëµÄÓ÷¨£º
void (* performMessage)(id,SEL);//¶¨ÒåÒ»¸öIMP£¨º¯ÊýÖ¸Õ룩 performMessage = (void (*)(id,SEL))[self methodForSelector:@selector(message)];
//ͨ¹ýmethodForSelector·½·¨¸ù¾ÝSEL»ñÈ¡¶ÔÓ¦µÄº¯ÊýÖ¸Õë performMessage(self,@selector(message));
//ͨ¹ýÈ¡µ½µÄIMP£¨º¯ÊýÖ¸Õë£©Ìø¹ýruntimeÏûÏ¢´«µÝ»úÖÆ£¬Ö±½ÓÖ´ÐÐmessage·½·¨ |
ÓÃIMP µÄ·½Ê½£¬Ê¡È¥ÁËruntimeÏûÏ¢´«µÝ¹ý³ÌÖÐËù×öµÄһϵÁж¯×÷£¬±ÈÖ±½ÓÏò¶ÔÏó·¢ËÍÏûÏ¢¸ßЧһЩ¡£
3¡¢´«µÝÏûÏ¢ËùÓõöruntime·½·¨
ÉÏÆªÎÄÕÂÖÐÎÒÃÇ˵¹ý£¬ÏÂÃæµÄ·½·¨£º
ÔÚ±àÒëºó»á±ä³É£º
objc_msgSend(receiver, selector) |
ʵ¼ÊÉÏ£¬Í¬objc_msgSend·½·¨ÀàËÆµÄ»¹Óм¸¸ö£º
objc_msgSend_stret£¨·µ»ØÖµÊǽṹÌ壩 objc_msgSend_fpret£¨·µ»ØÖµÊǸ¡µãÐÍ£© objc_msgSendSuper£¨µ÷Óø¸Àà·½·¨£© |
ËüÃǵÄ×÷Óö¼ÊÇÀàËÆµÄ£¬ÎªÁ˼òµ¥Æð¼û£¬ºóÐø½éÉÜÏûÏ¢ºÍÏûÏ¢´«µÝ»úÖÆ¶¼ÒÔobjc_msgSend·½·¨ÎªÀý¡£
¶þ¡¢ÏûÏ¢µ÷ÓÃÁ÷³Ì
Ò»Çл¹ÊÇ´ÓÏûÏ¢±í´ïʽ[receiver message]¿ªÊ¼£¬ÔÚ±»×ª»»³Éobjc_msgSend(receiver,
SEL)ºó£¬ÔÚÔËÐÐʱ£¬runtime system»á×öÒÔÏÂÊÂÇ飺
1¡¢¼ì²éºöÂÔµÄSelector£¬±ÈÈçµ±ÎÒÃÇÔËÐÐÔÚÓÐÀ¬»ø»ØÊÕ»úÖÆµÄ»·¾³ÖУ¬½«»áºöÂÔretainºÍreleaseÏûÏ¢¡£
2¡¢¼ì²éreceiverÊÇ·ñΪnil¡£²»ÏñÆäËûÓïÑÔ£¬nilÔÚobjective-CÖÐÊÇÍêÈ«ºÏ·¨µÄ£¬²¢ÇÒÕâÀïÓкܶàÔÒòÄãÒ²Ô¸ÒâÕâÑù£¬±ÈÈ磬ÖÁÉÙÎÒÃÇʡȥÁ˸øÒ»¸ö¶ÔÏó·¢ËÍÏûϢǰ¼ì²é¶ÔÏóÊÇ·ñΪ¿ÕµÄ²Ù×÷¡£Èç¹ûreceiverΪ¿Õ£¬Ôò»á½«
selectorÒ²ÉèÖÃΪ¿Õ£¬²¢ÇÒÖ±½Ó·µ»Øµ½ÏûÏ¢µ÷Óõĵط½¡£Èç¹û¶ÔÏó·Ç¿Õ£¬¾Í¼ÌÐøÏÂÒ»²½¡£
3¡¢½ÓÏÂÀ´»á¸ù¾ÝSELµ½µ±Ç°ÀàÖвéÕÒ¶ÔÓ¦µÄIMP£¬Ê×ÏÈ»áÔÚcacheÖмìË÷Ëü£¬Èç¹ûÕÒµ½Á˾͸ù¾Ýº¯ÊýÖ¸ÕëÌø×ªµ½Õâ¸öº¯ÊýÖ´ÐУ¬·ñÔò½øÐÐÏÂÒ»²½¡£
4¡¢¼ìË÷µ±Ç°Àà¶ÔÏóÖеķ½·¨±í£¨method list£©£¬Èç¹ûÕÒµ½ÁË£¬¼ÓÈëcacheÖУ¬²¢ÇÒ¾ÍÌø×ªµ½Õâ¸öº¯ÊýÖ®ÐУ¬·ñÔò½øÐÐÏÂÒ»²½¡£
5¡¢´Ó¸¸ÀàÖÐѰÕÒ,Ö±µ½¸ùÀࣺNSObjectÀà¡£ÕÒµ½Á˾ͽ«·½·¨¼ÓÈë¶ÔÓ¦ÀàµÄcache±íÖУ¬Èç¹ûÈÔΪÕÒµ½£¬ÔòÒª½øÈëºóÎĽéÉܵÄÄÚÈÝ£º¶¯Ì¬·½·¨¾öÒé¡£
6¡¢Èç¹û¶¯Ì¬·½·¨¾öÒéÈÔ²»Äܽâ¾öÎÊÌ⣬ֻÄܽøÐÐ×îºóÒ»´Î³¢ÊÔ£¬½øÈëÏûϢת·¢Á÷³Ì¡£
7¡¢Èç¹û»¹²»ÐУ¬È¥ËÀ°É¡£
ÏÂÃæµÄͼ²¿·ÖչʾÁËÕâ¸öµ÷Óùý³Ì£º

дµ½Õâ´ó¼Ò¿Ï¶¨»á·¢³öÕâÑùµÄÒÉÎÊ£ºÎÒ½ö½öÏëµ÷ÓÃÒ»¸ö·½·¨¶øÒÑ£¬È´²»µÃ²»¾ÀúÄÇô¶à²½Ö裬ЧÂÊÉÏÔõô±£Ö¤£¿£¿Æ»¹ûÒ²×öÁËһЩÓÅ»¯ÉϵŤ×÷¡£
Èý¡¢º¯Êý¼ìË÷ÓÅ»¯´ëÊ©
Ö÷Òª´ÓÏÂÃæÁ½¸ö·½Ãæ×ÅÊÖ£º
1¡¢Í¨¹ýSEL½øÐÐIMPÆ¥Åä
ÏÈÀ´¿´¿´Àà¶ÔÏóÖб£´æµÄ·½·¨ÁбíºÍ·½·¨µÄÊý¾Ý½á¹¹£º
typedef struct method_list_t { uint32_t entsize_NEVER_USE; uint32_t count; struct method_t first; } method_list_t; typedef struct method_t { SEL name; const char *types;//²ÎÊýÀàÐͺͷµ»ØÖµÀàÐÍ IMP imp; } method_t; |
ÔÚǰһƪÎÄÕ½éÉÜSELµÄʱºò£¬ÎÒÃÇÒѾ˵¹ýÁËÆ»¹ûÔÚͨ¹ýSEL¼ìË÷IMPʱ×öµÄŬÁ¦£¬ÕâÀï²»ÔÙÀÛÊö¡£
2¡¢cache»º´æ
cacheµÄÔÔò¾ÍÊÇ»º´æÄÇЩ¿ÉÄÜÒªÖ´Ðеĺ¯ÊýµØÖ·£¬ÄÇôÏ´ε÷ÓõÄʱºò£¬ËٶȾͿÉÒÔ¿ìËٺܶࡣÕâ¸öºÍCPUµÄ¸÷ÖÖ»º´æÔÀíÏàͨ¡£ºÃ°É£¬ËµÁËÕâô¶àÁË£¬ÔÙÀ´ÈÏʶ¼¸¸öÃû´Ê£º
struct objc_cache { uintptr_t mask; uintptr_t occupied; cache_entry *buckets[1]; }; typedef struct { SEL name; void *unused; IMP imp; } cache_entry; |
¿´Õâ¸ö½á¹¹£¬ÓÐûÓиã´íÓÖÊÇhash table¡£
objc_msgSend Ê×ÏÈÔÚcache list ÖÐÕÒSEL£¬Ã»ÓÐÕÒµ½¾ÍÔÚclass
methodÖÐÕÒ£¬super class methodÖÐÕÒ£¨µ±È»super class Ò²ÓÐcache
list£©¡£¶øcacheµÄ»úÖÆÔò·Ç³£¸´ÔÓÁË£¬ÓÉÓÚObjective-CÊǶ¯Ì¬ÓïÑÔ¡£ËùÒÔ£¬ÕâÀïÃæ»¹ÓкܶàµÄ¶àÏß³Ìͬ²½ÎÊÌ⣬¶øÕâÐ©ËøÓÖÊÇЧÂʵĴóµÐ£¬Ïà¹ØµÄÄÚÈÝÒѾԶԶ³¬¹ý±¾ÎÄÌÖÂ۵ķ¶Î§¡£
Èç¹ûÔÚ»º´æÖÐÒѾÓÐÁËÐèÒªµÄ·½·¨Ñ¡±ê,ÔòÏûÏ¢½ö½ö±Èº¯Êýµ÷ÓÃÂýÒ»µãµã¡£Èç¹û³ÌÐòÔËÐÐÁË×ã¹»³¤µÄʱ¼ä,¼¸ºõÿ¸öÏûÏ¢¶¼ÄÜÔÚ»º´æÖÐÕÒµ½·½·¨ÊµÏÖ¡£³ÌÐòÔËÐÐʱ,»º´æÒ²½«Ëæ×ÅеÄÏûÏ¢µÄÔö¼Ó¶øÔö¼Ó¡£¾ÝÅ£ÈË˵£¨Ã»ÓÐÇײâ¹ý£©£¬Æ»¹ûͨ¹ýÕâЩÓÅ»¯£¬Ê¹ÏûÏ¢´«µÝºÍÖ±½ÓµÄº¯Êýµ÷ÓÃЧÂÊÉϵIJî¾àÒѾÏ൱µÄС¡£
ËÄ¡¢·½·¨µ÷ÓÃÖеÄÒþ²Ø²ÎÊý
Ç×°®µÄObjective-C³ÌÐòÔ±ÃÇ£¬ÄãÃÇÔÚ½øÐÐÃæÏò¶ÔÏó±à³ÌµÄʱºò£¬ÔÚʵÀý·½·¨Öж¼ÊÇÓùýself¹Ø¼ü×Ö°É£¬¿ÉÊÇÄãÓÐûÓÐÏë¹ý£¬ÎªÊ²Ã´ÔÚÒ»¸öʵÀý·½·¨ÖУ¬Í¨¹ýself¹Ø¼ü×Ö¾ÍÄÜÈ¡µ½µ÷Óõ±Ç°·½·¨µÄ¶ÔÏóÄØ£¿Õâ¾ÍÒª¹é¹¦Óëruntime
systemÏûÏ¢µÄÒþ²Ø²ÎÊýÁË¡££¨×¢£ºÔÚ´ËÐÞÕý£¬Àà·½·¨ºÍʵÀý·½·¨ÖУ¬¶¼¿ÉÒÔ·ÃÎÊselfºÍ_cmdÕâÁ½¸öÊôÐÔ£¬ÒòΪËüÃǶ¼²»ÊôÓÚÀàµÄʵÀý±äÁ¿£¬¶øÊÇÐβΣ¡£¡£¡£¡Îóµ¼´ó¼ÒÁË£¬Éî±íǸÒ⣡£¡£¡£¡£©
µ±objc_msgSendÕÒµ½·½·¨¶ÔÓ¦µÄʵÏÖʱ,Ëü½«Ö±½Óµ÷Óø÷½·¨ÊµÏÖ,²¢½«ÏûÏ¢ÖÐËùÓеIJÎÊý¶¼´«µÝ¸ø·½·¨ÊµÏÖ,ͬʱ,Ëü»¹½«´«µÝÁ½¸öÒþ²ØµÄ²ÎÊý:
1.½ÓÊÕÏûÏ¢µÄ¶ÔÏó£¨Ò²¾ÍÊÇselfÖ¸ÏòµÄÄÚÈÝ£©
2.·½·¨Ñ¡±ê£¨_cmdÖ¸ÏòµÄÄÚÈÝ£©
ÕâЩ²ÎÊý°ïÖú·½·¨ÊµÏÖ»ñµÃÁËÏûÏ¢±í´ïʽµÄÐÅÏ¢¡£ËüÃDZ»ÈÏΪÊÇ¡±Òþ²Ø¡°µÄÊÇÒòΪËüÃDz¢Ã»ÓÐÔÚ¶¨Òå·½·¨µÄÔ´´úÂëÖÐÉùÃ÷,¶øÊÇÔÚ´úÂë±àÒëʱÊDzåÈë·½·¨µÄʵÏÖÖеġ£¾¡¹ÜÕâЩ²ÎÊýûÓб»ÏÔʾÉùÃ÷,µ«ÔÚÔ´´úÂëÖÐÈÔÈ»¿ÉÒÔÒýÓÃËüÃÇ(¾ÍÏó¿ÉÒÔÒýÓÃÏûÏ¢½ÓÊÕÕß¶ÔÏóµÄʵÀý±ä
Á¿Ò»Ñù)¡£ÔÚ·½·¨ÖпÉÒÔͨ¹ý self À´ÒýÓÃÏûÏ¢½ÓÊÕÕß¶ÔÏó,ͨ¹ýÑ¡±ê_cmd À´ÒýÓ÷½·¨±¾Éí¡£ÏÂÃæµÄÀý×ӺܺõÄ˵Ã÷ÁËÕâ¸öÎÊÌ⣺
- (void)message { self.name = @"James";//ͨ¹ýself¹Ø¼ü×Ö¸øµ±Ç°¶ÔÏóµÄÊôÐÔ¸³Öµ SEL currentSel = _cmd;//ͨ¹ý_cmd¹Ø¼ü×ÖÈ¡µ½µ±Ç°º¯Êý¶ÔÓ¦µÄSEL NSLog(@"currentSel is :%s",(char *)currentSel); } |
´òÓ¡½á¹û£º
ObjcRunTime[693:403] currentSel is :message |
µ±È»£¬ÔÚÕâÁ½¸ö²ÎÊýÖÐ,self ¸üÓÐÓ㬸ü³£ÓÃһЩ¡£Êµ¼ÊÉÏ,ËüÊÇÔÚ·½·¨ÊµÏÖÖзÃÎÊÏûÏ¢½ÓÊÕÕß¶ÔÏóµÄʵÀý±äÁ¿µÄ;¾¶¡£
Objective-C runtimeÖ®ÏûϢת·¢»úÖÆ£¨Èý£©
ѧÁËÄÇô¾ÃµÄObjective-C£¬¸øÎҵĸоõ¾ÍÊÇËüʲô¶¼ÊǶ¯Ì¬µÄ£¬Ä㽫»áÌýµ½Ò»¸öеÄÃû´Ê£º
Ò»¡¢¶¯Ì¬·½·¨½âÎö
1¡¢+(BOOL) resolveInstanceMethod:(SEL)
sel
ÕâÊÇNSObject¸ùÀàÌṩµÄÀà·½·¨£¬µ÷ÓÃʱ»úΪµ±±»µ÷Óõķ½·¨ÊµÏÖ²¿·ÖûÓÐÕÒµ½£¬¶øÏûϢת·¢»úÖÆÆô¶¯Ö®Ç°µÄÕâ¸öÖмäʱ¿Ì¡£
2¡¢@dynamic¹Ø¼ü×Ö
Objective-C2.0 ÌṩÁË@dynamic¹Ø¼ü×Ö¡£Õâ¸ö¹Ø¼ü×ÖÓÐÁ½¸ö×÷Óãº
¢Ù¸æËß±àÒëÆ÷²»Òª´´½¨ÊµÏÖÊôÐÔËùÓõÄʵÀý±äÁ¿£»
¢Ú¸æËß±àÒëÆ÷²»Òª´´½¨¸ÃÊôÐÔµÄgetºÍsetter·½·¨¡£
Èç¹ûÎÒÃÇÔÚ@interface½Ó¿ÚÎļþÖÐÉùÃ÷ÁËÒ»¸öÊôÐÔ£¬ÈçÏÂËùʾ£º
@property(nonatomic,retain) NSString *name; |
ĬÈÏÇé¿öÏ£¬±àÒëÆ÷»áΪµ±Ç°Àà×Ô¶¯Éú³ÉÒ»¸öNSString *_nameµÄʵÀý±äÁ¿£¨Èç¹ûÏë¸Ä±äʵÀý±äÁ¿µÄÃû³Æ¿ÉÒÔÓÃ@synthesize¹Ø¼ü×Ö£©£¬Í¬Ê±»áÉú³ÉÁ½¸öÃûΪ-
(NSString *)nameºÍ- (void)setName:(NSString *)aNameµÄ´æÈ¡·½·¨¡£
¶ø@dynamic¹Ø¼ü×Ö¾ÍÊǸæËß±àÒëÆ÷²»Òª×öÕâЩÊ£¬Í¬Ê±ÔÚʹÓÃÁË´æÈ¡·½·¨Ê±Ò²²»Òª±¨´í£¬¼´ÈñàÒëÆ÷ÏàÐÅ´æÈ¡·½·¨»áÔÚÔËÐÐʱÕÒµ½¡£
±ÈÈçÔÚ@implementationÎļþÖÐ×öÁËÈçÏÂÉùÃ÷£º
Èç¹ûʹÓÃÁËnameÊôÐÔµÄsetter·½·¨£¬ÓÖ²»ÏëÔÚÔËÐÐʱ±ÀÀ££¬¾Í¿ÉÒÔÔÚÔËÐÐʱ×öµã¶¯×÷£º
void dynamicMethodIMP(id self, SEL _cmd) { // implementation .... } + (BOOL)resolveInstanceMethod:(SEL)sel { NSLog(@"sel is %@", NSStringFromSelector(sel)); if(sel == @selector(setName:)){ class_addMethod([self class],sel,(IMP)dynamicMethodIMP,"v@:"); return YES; } return [super resolveInstanceMethod:sel]; } |
ÔÚresolveInstanceMethodµÄʵÏÖÖУ¬ÎÒÃÇͨ¹ýclass_addMethod·½·¨¶¯Ì¬µÄÏòµ±Ç°¶ÔÏóÔö¼ÓÁËdynamicMethodIMPº¯Êý£¬À´´úÌæ-(void)setName:(NSString
*)nameµÄʵÏÖ²¿·Ö£¬´Ó¶ø´ïµ½Á˶¯Ì¬Éú³ÉnameÊôÐÔ·½·¨µÄÄ¿µÄ¡£
ÖµµÃ˵Ã÷µÄÊÇ£º
¢ÙÔÚÉϸöÀý×ÓÖУ¬ÎÒÃÇ×Ô¼ºÊµÏÖÁË-(void)setName:(NSString *)name·½·¨£¬ÔòÔÚÔËÐеÄʱºò£¬µ÷ÓÃÍêÎÒÃÇʵÏÖµÄ-(void)setName:(NSString
*)name·½·¨ºó£¬ÔËÐÐʱϵͳÈÔÈ»»áµ÷+(BOOL) resolveInstanceMethod:(SEL)
sel·½·¨£¬Ö»²»¹ýÕâÀïµÄsel»á±ä³É_doZombieMe£¬´Ó¶øÎÒÃÇʵÏÖÖØ¶¨ÏòµÄif·ÖÖ§¾Í½ø²»È¥ÁË£¬¼´ÎÒÃÇʵÏֵķ½·¨²»»á±»¸²¸Ç¡£
¢Ú"v@:"ÊôÓÚObjective-CÀàÐͱàÂëµÄÄÚÈÝ£¬¸ÐÐËȤµÄͬѧ¿ÉÒÔ×Ô¼ºgoogleһϡ£
¶þ¡¢runtime systemÏûϢת·¢»úÖÆ
¶ÔÏóÊÇÇ«¹§µÄ£¬Ëü»á½ÓÊÕËùÓз¢Ë͹ýÀ´µÄÏûÏ¢£¬ÄÄÅÂÕâЩÏûÏ¢×Ô¼ºÎÞ·¨ÏìÓ¦¡£ÎÊÌâÀ´ÁË£ºµ±¶ÔÏóÎÞ·¨ÏìÓ¦ÕâЩÏûϢʱÔõô°ì£¿runtimeÌṩÁËÏûϢת·¢»úÖÆÀ´´¦Àí¸ÃÎÊÌâ¡£
µ±Íⲿµ÷ÓõÄij¸ö·½·¨¶ÔÏóûÓÐʵÏÖ£¬¶øÇÒresolveInstanceMethod·½·¨ÖÐҲûÓÐ×öÖØ¶¨Ïò´¦Àíʱ£¬¾Í»á´¥·¢-
(void)forwardInvocation:(NSInvocation *)anInvocation·½·¨¡£Ôڸ÷½·¨ÖУ¬¿ÉÒÔʵÏÖ¶Ô²»ÄÜ´¦ÀíµÄÏûÏ¢×öµÄһЩĬÈÏ´¦Àí,Ò²¿ÉÒÔÒÔÆäËüµÄijÖÖ·½Ê½À´±ÜÃâ´íÎó±»Å׳ö¡£ÏñforwardInvocation:µÄÃû×ÖÒ»Ñù,Õâ¸ö·½·¨Í¨³£ÓÃÀ´½«²»ÄÜ´¦ÀíµÄÏûϢת·¢¸øÆäËüµÄ¶ÔÏó¡£Í¨³£ÎÒÃÇÖØÐ´¸Ã·½·¨µÄ·½Ê½ÈçÏÂËùʾ£º
-(void)forwardInvocation:(NSInvocation *)invocation { SEL invSEL = invocation.selector; if ([someOtherObject respondsToSelector:invSEL]) [anInvocation invokeWithTarget:someOtherObject]; } else { [self doesNotRecognizeSelector:invSEL]; } } |
Ôõô¿´×ÅÓеãÏñ¶à¼Ì³Ðѽ£¿£¿£¿Äã˵¶ÔÁË£¬ÏûϢת·¢ÌṩÁ˶àÖØ¼Ì³ÐµÄºÜ¶àÌØÐÔ¡£È»¶ø,Á½ÕßÓкܴóµÄ²»Í¬:¶àÖØ¼Ì³ÐÊǽ«²»Í¬µÄÐÐΪ·â×°µ½µ¥¸öµÄ¶ÔÏóÖÐ,ÓпÉÄܵ¼ÖÂÅÓ´óµÄ,¸´ÔӵĶÔÏó¡£¶øÏûϢת·¢Êǽ«ÎÊÌâ·Ö½âµ½¸üСµÄ¶ÔÏóÖÐ,µ«ÊÇÓÖÒÔÒ»ÖÖ¶ÔÏûÏ¢·¢ËͶÔÏóÀ´ËµÍêȫ͸Ã÷µÄ·½Ê½½«ÕâЩ¶ÔÏóÁªÏµÆðÀ´¡£×ÜÖ®£¬Objective-Cͨ¹ýÕâÖÖ·½Ê½£¬Ò»¶¨³Ì¶ÈÉϼõСÁË×Ô¼º²»Ö§³Ö¶à¼Ì³ÐµÄÁÓÊÆ¡£
¾¹ý°ë¸öÔµÄʱ¼ä£¬×Ô¼º×ܽᡢÕûÀí³öÁËÕâÈýƪÎÄÕ£¬µ½ÕâÀ¶ÔObjective-CÔËÐÐʱµÄѧϰËãÊǸæÒ»¶ÎÂäÁË¡£ÎıʵÄÔÒò£¬ÎÄÕ½ṹ²»ÊǺÜÇåÎú£¬»¹Çë¼ûÁ¡£¶ÔÔËÐÐʱÀí½â²»µ½Î»£¬»òÕßÊÇÓдíÎóµÄµØ·½£¬»¹Çë¹ã´ó²©ÓÑÖ¸³ö£¬¸Ð¼¤²»¾¡£¡
|