SwiftÊÇÆ»¹û2014Äê·¢²¼µÄ±à³Ì¿ª·¢ÓïÑÔ£¬¿ÉÓëObjective-C¹²Í¬ÔËÐÐÓÚMac
OSºÍiOSƽ̨£¬ÓÃÓڴ»ùÓÚÆ»¹ûƽ̨µÄÓ¦ÓóÌÐò¡£SwiftÒѾ¿ªÔ´£¬Ä¿Ç°×îа汾Ϊ2.2¡£ÎÒÃÇÖªµÀObjective-CÊǾßÓж¯Ì¬ÐԵģ¬Äܹ»Í¨¹ýruntime
APIµ÷ÓúÍÌæ»»ÈÎÒâ·½·¨£¬ÄÇSwiftÒ²¾ßÓÐÕâЩ¶¯Ì¬ÐÔÂð£¿
·ÖÎöÓÃÀý
ÎÒÃÇÄÃÒ»¸ö´¿SwiftÀàºÍÒ»¸ö¼Ì³Ð×ÔNSObjectµÄÀàÀ´×ö·ÖÎö£¬ÕâÁ½¸öÀàÀï°üº¬¾¡Á¿¶àµÄSwiftµÄÀàÐͱÈÈçCharacter¡¢String¡¢AnyObject¡¢Tuple¡£
´úÂëÈçÏ£º
(µã»÷·Å´óͼÏñ)

·½·¨¡¢ÊôÐÔ
¶¯Ì¬ÐԱȽÏÖØÒªµÄÒ»µã¾ÍÊÇÄܹ»Äõ½Ä³¸öÀàËùÓеķ½·¨¡¢ÊôÐÔ£¬ÎÒÃÇʹÓÃÈçÏ´úÂëÀ´´òÓ¡·½·¨ºÍÊôÐÔÁÐ±í¡£
(µã»÷·Å´óͼÏñ)

µ÷ÓÃshowClsRuntimeµÄ´úÂëÈçÏ£º
let aSwiftClass:TestASwiftClass = TestASwiftClass(); showClsRuntime(object_getClass(aSwiftClass)); print("\n"); showClsRuntime(object_getClass(self)); |
¿´¿´ÎÒÃǵõ½Ê²Ã´½á¹û£¿ (µã»÷·Å´óͼÏñ)

* ¶ÔÓÚ´¿SwiftµÄTestASwiftClassÀ´ËµÈκη½·¨¡¢ÊôÐÔ¶¼Î´»ñÈ¡µ½
* ¶ÔÓÚTestSwiftVCÀ´Ëµ³ýtestReturnTuple¡¢
testReturnVoidWithaCharacterÁ½¸ö·½·¨Í⣬ÆäËûµÄ¶¼»ñÈ¡³É¹¦ÁË¡£
ÕâÊÇΪʲô£¿
´¿SwiftÀàµÄº¯Êýµ÷ÓÃÒѾ²»ÔÙÊÇObjective-cµÄÔËÐÐʱ·¢ÏûÏ¢£¬¶øÊÇÀàËÆC++µÄvtable£¬ÔÚ±àÒëʱ¾ÍÈ·¶¨Á˵÷ÓÃÄĸöº¯Êý£¬ËùÒÔû·¨Í¨¹ýruntime»ñÈ¡·½·¨¡¢ÊôÐÔ¡£
TestSwiftVC¼Ì³Ð×ÔUIViewController£¬»ùÀàΪNSObject£¬¶øSwiftΪÁ˼æÈÝObjective-C£¬·²ÊǼ̳Ð×ÔNSObjectµÄÀà¶¼»á±£ÁôÆä¶¯Ì¬ÐÔ£¬ËùÒÔÎÒÃÇÄÜͨ¹ýruntimeÄõ½ËûµÄ·½·¨¡£
µ«ÎªÊ²Ã´testReturnTuple
testReturnVoidWithaCharacterÈ´ÓÖ»ñÈ¡²»µ½ÄØ£¿
´ÓObjective-cµÄruntime ÌØÐÔ¿ÉÒÔÖªµÀ£¬ËùÓÐÔËÐÐʱ·½·¨¶¼ÒÀÀµTypeEncoding£¬Ò²¾ÍÊÇmethod_getTypeEncoding·µ»ØµÄ½á¹û£¬ËûÖ¸¶¨ÁË·½·¨µÄ²ÎÊýÀàÐÍÒÔ¼°ÔÚº¯Êýµ÷ÓÃʱ²ÎÊýÈëÕ»ËùÒªµÄÄÚ´æ¿Õ¼ä£¬Ã»ÓÐÕâ¸ö±êʶ¾ÍÎÞ·¨¶¯Ì¬µÄѹÈë²ÎÊý£¨±ÈÈçtestReturnVoidWithaId:
Optional("v24@0:8@16") Optional("v")£¬±íʾ´Ë·½·¨²ÎÊý¹²Ðè24¸ö×Ö½Ú£¬·µ»ØÖµÎªvoid£¬µÚÒ»¸ö²ÎÊýΪid£¬µÚ¶þ¸öΪselector£¬µÚÈý¸öΪid£©£¬¶øCharacterºÍTupleÊÇSwiftÌØÓеģ¬ÎÞ·¨Ó³Éäµ½OCµÄÀàÐÍ£¬¸üÎÞ·¨ÓÃOCµÄtypeEncoding±íʾ£¬Ò²¾Íû·¨Í¨¹ýruntime»ñÈ¡ÁË¡£
Method Swizzling
¶¯Ì¬ÐÔ×î³£ÓõľÍÊÇ·½·¨Ìæ»»£¨Method Swizzling£©£¬½«ÀàµÄij¸ö·½·¨Ìæ»»³É×Ô¶¨ÒåµÄ·½·¨£¬´Ó¶ø´ïµ½hookµÄ×÷Óá£
¶ÔÓÚ´¿SwiftÀࣨÈçTestASwiftClass£©À´Ëµ£¬ÎÞ·¨Í¨¹ýobjc runtimeÌæ»»·½·¨£¬ÒòΪÓÉÉÏÃæµÄ²âÊÔ¿ÉÖªÄò»µ½ÕâЩ·½·¨¡¢ÊôÐÔ
¶ÔÓڼ̳Ð×ÔNSObjectÀࣨÈçTestSwiftVC£©À´Ëµ£¬ÎÞ·¨Í¨¹ýruntime»ñÈ¡µ½µÄ·½·¨¿Ï¶¨Ã»·¨Ìæ»»ÁË¡£ÄÇÄÜͨ¹ýruntime»ñÈ¡µ½µÄ·½·¨¾Í¶¼Äܱ»Ìæ»»Âð£¿ÎÒÃDzâÒ»°Ñ¡£Method
SwizzlingµÄ´úÂëÈçÏÂ
(µã»÷·Å´óͼÏñ)

ÎÒÃÇÌæ»»Á½¸ö¿ÉÒÔ±»runtime»ñÈ¡µ½µÄ·½·¨£ºviewDidAppearºÍtestReturnVoidWithaId
(µã»÷·Å´óͼÏñ)

´òÓ¡µÄÈÕ־Ϊ
F:testReturnVoidWithaId L:50 F:sz_viewDidAppear L:46 |
˵Ã÷viewDidAppearÒѾ±»Ìæ»»£¬µ«ÊÇtestReturnVoidWithaIdȴûÓб»Ìæ»»£¬ÕâÊÇΪºÎ?
ÎÒÃÇÔÚ·½·¨Àï´ò¸ö¶Ïµã¿´¿´£¬Èçͼ:
(µã»÷·Å´óͼÏñ)

(µã»÷·Å´óͼÏñ)

¿ÉÒÔ¿´µ½Çø±ð£¬µ÷ÓÃsz_viewDidAppearÕ»µÄǰһ֡Ϊ@objc TestSwiftVC.sz_viewDidAppear(Bool)
-> ()Óиö@objc±êʶ£¬¶øµ÷ÓÃtestReturnVoidWithaIdÔòûÓд˱êʶ¡£
@objcÓÃÀ´×öʲôµÄ£¿Ó붯̬ÐÔÓйØÂð£¿
> @objc
ÕÒµ½¹Ù·½Îĵµ¶Á¶Á¡£
¿ÉÒÔÖªµÀ@objcÊÇÓÃÀ´½«SwiftµÄAPIµ¼³ö¸øObjective-CºÍObjective-C runtimeʹÓõģ¬Èç¹ûÄãµÄÀà¼Ì³Ð×ÔObjective-cµÄÀࣨÈçNSObject£©½«»á×Ô¶¯±»±àÒëÆ÷²åÈë@objc±êʶ¡£
ÎÒÃÇÔÚ°ÑTestASwiftClass£¨´¿SwiftÀࣩµÄ·½·¨¡¢ÊôÐÔǰ¶¼¼Ó¸ö@objc ÊÔÊÔ£¬Èçͼ£º
(µã»÷·Å´óͼÏñ)

²é¿´ÈÕÖ¾¿ÉÒÔ·¢ÏÖ¼ÓÁË@objcµÄ·½·¨¡¢ÊôÐÔ¾ù¿ÉÒÔ±»runtime»ñÈ¡µ½ÁË¡£
(µã»÷·Å´óͼÏñ)

dynamic
ÎĵµÀﻹÓÐÒ»¾ä˵Ã÷£º
¼ÓÁË@objc±êʶµÄ·½·¨¡¢ÊôÐÔÎÞ·¨±£Ö¤¶¼»á±»ÔËÐÐʱµ÷Óã¬
ÒòΪSwift»á×ö¾²Ì¬ÓÅ»¯¡£ÒªÏëÍêÈ«±»¶¯Ì¬µ÷Ó㬱ØÐëʹÓÃdynamicÐÞÊΡ£
ʹÓÃdynamicÐÞÊν«»áÒþʽµÄ¼ÓÉÏ@objc±êʶ
ÕâÒ²¾Í½âÊÍÁËΪʲôtestReturnVoidWithaIdÎÞ·¨±»Ìæ»»£¬ÒòΪдÔÚSwiftÀïµÄ´úÂëÖ±½Ó±»±àÒëÓÅ»¯³É¾²Ì¬µ÷ÓÃÁË¡£
¶øviewDidAppearÊǼ̳ÐObjective-CÀà»ñµÃµÄ·½·¨£¬±¾Éí¾Í±»ÐÞÊÎΪdynamic£¬ËùÒÔÄܱ»¶¯Ì¬Ìæ»»¡£
ÎÒÃǰÑTestSwiftVC·½·¨Ç°¼ÓÉÏdynamicÔÙ²âÒ»°Ñ£¬Èçͼ£º
(µã»÷·Å´óͼÏñ)

´Ó¶ÑÕ»Ò²¿ÉÒÔ¿´³ö£¬·½·¨µÄµ÷ÓÃǰÔö¼ÓÁË@objc±êʶ£¬testReturnVoidWithaId·½·¨±»Ìæ»»³É¹¦ÁË¡£
ͬÑùµÄ×ö·¨£¬ÎÒÃǰÑTestASwiftClassµÄ·½·¨ºÍÊôÐÔÒ²¶¼¼ÓÉÏdynamicÐÞÊΣ¬×öMethod
Swizzling£¬Í¬Ñù»ñµÃ³É¹¦£¬Èçͼ
(µã»÷·Å´óͼÏñ)

Objective-C»ñÈ¡Swift runtimeÐÅÏ¢
ÔÚObjective-c´úÂëÀïʹÓÃobjc_getClass("TestSwiftVC");»á·¢ÏÖ·µ»ØÖµÎª¿Õ£¬ÕâÊÇΪʲô?Swift´úÂëÖеÄTestSwiftVCÀ࣬ÔÚOCÖл¹ÊÇÕâ¸öÃû×ÖÂð£¿
ÎÒÃdzõʼ»¯Ò»¸ö¶ÔÏ󣬲¢¶ÏµãºÍ´òÓ¡¿´¿´£¬ÈçÏÂͼ£º
(µã»÷·Å´óͼÏñ)

¿ÉÒÔ¿´µ½SwiftÖеÄTestSwiftVCÀàÔÚOCÖеÄÀàÃûÒѾ±ä³ÉTestSwift.TestSwiftVC£¬¼´¹æÔòΪSWIFT_MODULE_NAME.ÀàÃû³Æ£¬ÔÚÆÕͨԴÂëÏîÄ¿ÀïSWIFT_MODULE_NAME¼´ÎªProductName£¬ÔÚ´òºÃµÄCocoa
Touch FrameworkÀïΪÔòΪµ¼³öµÄ°üÃû¡£
ËùÒÔÒªÏë´ÓObjective-cÖлñÈ¡SwiftÀàµÄruntimeÐÅÏ¢µÃÕâÑùд£º
id cls = objc_getClass("TestSwift.TestASwiftClass"); showClsRuntime(cls); id cls2 = objc_getClass("TestSwift.TestSwiftVC"); showClsRuntime(cls2); |
Objective-CÌæ»»Swiftº¯Êý ¸øTestSwiftVCºÍTestASwiftClassµÄtestReturnVoidWithaIdº¯Êý¼ÓÉÏdynamicÐÞÊΣ¬È»ºóÎÒÃÇÔÚObjective-C´úÂëÀïÌæ»»ÎªtestReturnVoidWithaIdImpº¯Êý£º
(µã»÷·Å´óͼÏñ)

ÔËÐÐÖ®ºóÎÒÃǵõ½½á¹û
F:void testReturnVoidWithaIdImp (__strong id, SEL, __strong id) L:20 self=<TestSwift.TestSwiftVC: 0x7fb4e1d148f0> F:void testReturnVoidWithaIdImp (__strong id, SEL, __strong id) L:20 self=TestSwift.TestASwiftClass |
˵Ã÷Á½Õߵķ½·¨ÔÚ¼ÓÉÏdynamicÐÞÊκ󣬾ùÄÜÔÚObjective-cÀï±»Ìæ»»¡£(TestSwiftVCµÄtestReturnVoidWithaId²»¼ÓdynamicÒ²»á´òÓ¡ÈÕÖ¾£¬ÎªÊ²Ã´£¿Áô¸ø¶ÁÕß˼¿¼)
×ܽá
´¿SwiftÀàûÓж¯Ì¬ÐÔ£¬µ«ÔÚ·½·¨¡¢ÊôÐÔǰÌí¼ÓdynamicÐÞÊοÉÒÔ»ñµÃ¶¯Ì¬ÐÔ¡£
¼Ì³Ð×ÔNSObjectµÄSwiftÀ࣬Æä¼Ì³Ð×Ô¸¸ÀàµÄ·½·¨¾ßÓж¯Ì¬ÐÔ£¬ÆäËû×Ô¶¨Òå·½·¨¡¢ÊôÐÔÐèÒª¼ÓdynamicÐÞÊβſÉÒÔ»ñµÃ¶¯Ì¬ÐÔ¡£
Èô·½·¨µÄ²ÎÊý¡¢ÊôÐÔÀàÐÍΪSwiftÌØÓС¢ÎÞ·¨Ó³Éäµ½Objective-CµÄÀàÐÍ(ÈçCharacter¡¢Tuple)£¬Ôò´Ë·½·¨¡¢ÊôÐÔÎÞ·¨Ìí¼ÓdynamicÐÞÊΣ¨»á±àÒë´íÎó£©
SwiftÀàÔÚObjective-CÖлáÓÐÄ£¿éǰ׺
|