ÒëÕß×¢:
֮ǰ¿´ÁËºÜ¶à¹ØÓÚ Swift ÅÉ·¢»úÖÆµÄÄÚÈÝ, µ«¸Ð¾õûÓÐһƪÄܹ»³¹µ×½²Çå³þÕâ¼þÊÂÇé, ¿´ÍêÁËÕâÆªÎÄÕÂÖ®ºóÎÒ¶Ô
Swift µÄÅÉ·¢»úÖÆ²Å½¨Á¢ÆðÁ˳õ²½µÄÈÏÖª.
ÕýÎÄ

Ò»Õűí×ܽáÒýÓÃÀàÐÍ, ÐÞÊηûºÍËüÃǶÔÓÚ Swift º¯ÊýÅÉ·¢·½Ê½µÄÓ°Ïì.
º¯ÊýÅÉ·¢¾ÍÊdzÌÐòÅжÏʹÓÃÄÄÖÖ;¾¶È¥µ÷ÓÃÒ»¸öº¯ÊýµÄ»úÖÆ. ÿ´Îº¯Êý±»µ÷ÓÃʱ¶¼»á±»´¥·¢, µ«ÄãÓÖ²»»áÌ«ÁôÒâµÄÒ»¸ö¶«Î÷.
Á˽âÅÉ·¢»úÖÆ¶ÔÓÚд³ö¸ßÐÔÄܵĴúÂëÀ´ËµºÜÓбØÒª, ¶øÇÒÒ²Äܹ»½âÊͺܶà Swift Àï¡±Ææ¹Ö¡±µÄÐÐΪ.
±àÒëÐÍÓïÑÔÓÐÈýÖÖ»ù´¡µÄº¯ÊýÅÉ·¢·½Ê½: Ö±½ÓÅÉ·¢(Direct Dispatch),
º¯Êý±íÅÉ·¢(Table Dispatch) ºÍ ÏûÏ¢»úÖÆÅÉ·¢(Message Dispatch), ÏÂÃæÎÒ»á×Ðϸ½²½âÕ⼸ÖÖ·½Ê½.
´ó¶àÊýÓïÑÔ¶¼»áÖ§³ÖÒ»µ½Á½ÖÖ, Java ĬÈÏʹÓú¯Êý±íÅÉ·¢, µ«Äã¿ÉÒÔͨ¹ý final ÐÞÊηûÐ޸ijÉÖ±½ÓÅÉ·¢.
C++ ĬÈÏʹÓÃÖ±½ÓÅÉ·¢, µ«¿ÉÒÔͨ¹ý¼ÓÉÏ virtual ÐÞÊηûÀ´¸Ä³Éº¯Êý±íÅÉ·¢. ¶ø Objective-C
Ôò×ÜÊÇʹÓÃÏûÏ¢»úÖÆÅÉ·¢, µ«ÔÊÐí¿ª·¢ÕßʹÓà C Ö±½ÓÅÉ·¢À´»ñÈ¡ÐÔÄܵÄÌá¸ß. ÕâÑùµÄ·½Ê½·Ç³£ºÃ, µ«Ò²¸øºÜ¶à¿ª·¢Õß´øÀ´ÁËÀ§ÈÅ,
ÅÉ·¢·½Ê½ (Types of Dispatch )
³ÌÐòÅÉ·¢µÄÄ¿µÄÊÇΪÁ˸æËß CPU ÐèÒª±»µ÷Óõĺ¯ÊýÔÚÄÄÀï, ÔÚÎÒÃÇÉîÈë Swift ÅÉ·¢»úÖÆÖ®Ç°, ÏÈÀ´Á˽âÒ»ÏÂÕâÈýÖÖÅÉ·¢·½Ê½,
ÒÔ¼°Ã¿ÖÖ·½Ê½ÔÚ¶¯Ì¬ÐÔºÍÐÔÄÜÖ®¼äµÄÈ¡Éá.
Ö±½ÓÅÉ·¢ (Direct Dispatch)
Ö±½ÓÅÉ·¢ÊÇ×î¿ìµÄ, ²»Ö¹ÊÇÒòΪÐèÒªµ÷ÓõÄÖ¸Á»á¸üÉÙ, ²¢ÇÒ±àÒëÆ÷»¹Äܹ»ÓкܴóµÄÓÅ»¯¿Õ¼ä, ÀýÈ纯ÊýÄÚÁªµÈ,
µ«Õâ²»ÔÚÕâÆª²©¿ÍµÄÌÖÂÛ·¶Î§. Ö±½ÓÅÉ·¢Ò²ÓÐÈ˳ÆÎª¾²Ì¬µ÷ÓÃ.
È»¶ø, ¶ÔÓÚ±à³ÌÀ´ËµÖ±½Óµ÷ÓÃÒ²ÊÇ×î´óµÄ¾ÖÏÞ, ¶øÇÒÒòΪȱ·¦¶¯Ì¬ÐÔËùÒÔû°ì·¨Ö§³Ö¼Ì³Ð.
º¯Êý±íÅÉ·¢ (Table Dispatch )
º¯Êý±íÅÉ·¢ÊDZàÒëÐÍÓïÑÔʵÏÖ¶¯Ì¬ÐÐΪ×î³£¼ûµÄʵÏÖ·½Ê½. º¯Êý±íʹÓÃÁËÒ»¸öÊý×éÀ´´æ´¢ÀàÉùÃ÷µÄÿһ¸öº¯ÊýµÄÖ¸Õë.
´ó²¿·ÖÓïÑÔ°ÑÕâ¸ö³ÆÎª ¡°virtual table¡±(Ð麯Êý±í), Swift Àï³ÆÎª ¡°witness
table¡±. ÿһ¸öÀà¶¼»áά»¤Ò»¸öº¯Êý±í, ÀïÃæ¼Ç¼×ÅÀàËùÓеĺ¯Êý, Èç¹û¸¸ÀຯÊý±» override
µÄ»°, ±íÀïÃæÖ»»á±£´æ±» override Ö®ºóµÄº¯Êý. Ò»¸ö×ÓÀàÐÂÌí¼ÓµÄº¯Êý, ¶¼»á±»²åÈëµ½Õâ¸öÊý×éµÄ×îºó.
ÔËÐÐʱ»á¸ù¾ÝÕâÒ»¸ö±íÈ¥¾ö¶¨Êµ¼ÊÒª±»µ÷Óõĺ¯Êý.
¾Ù¸öÀý×Ó, ¿´¿´ÏÂÃæÁ½¸öÀà:
class ParentClass { func method1() {} func method2() {} } class ChildClass: ParentClass { override func method2() {} func method3() {} } |
ÔÚÕâ¸öÇé¿öÏÂ, ±àÒëÆ÷»á´´½¨Á½¸öº¯Êý±í, Ò»¸öÊÇ ParentClass µÄ, ÁíÒ»¸öÊÇ ChildClassµÄ:

ÕâÕűíչʾÁË ParentClass ºÍ ChildClass ÐéÊý±íÀï method1, method2,
method3 ÔÚÄÚ´æÀïµÄ²¼¾Ö.
let obj = ChildClass() obj.method2() |
µ±Ò»¸öº¯Êý±»µ÷ÓÃʱ, »á¾ÀúÏÂÃæµÄ¼¸¸ö¹ý³Ì:
1.¶ÁÈ¡¶ÔÏó 0xB00 µÄº¯Êý±í.
2.¶ÁÈ¡º¯ÊýÖ¸ÕëµÄË÷Òý. ÔÚÕâÀï, method2 µÄË÷ÒýÊÇ1(Æ«ÒÆÁ¿),
Ò²¾ÍÊÇ 0xB00 + 1.
3.Ìøµ½ 0x222 (º¯ÊýÖ¸ÕëÖ¸Ïò 0x222)
²é±íÊÇÒ»ÖÖ¼òµ¥, Ò×ʵÏÖ, ¶øÇÒÐÔÄÜ¿ÉÔ¤ÖªµÄ·½Ê½. È»¶ø, ÕâÖÖÅÉ·¢·½Ê½±ÈÆðÖ±½ÓÅÉ·¢»¹ÊÇÂýÒ»µã.
´Ó×Ö½ÚÂë½Ç¶ÈÀ´¿´, ¶àÁËÁ½´Î¶ÁºÍÒ»´ÎÌø×ª, ÓÉ´Ë´øÀ´ÁËÐÔÄܵÄËðºÄ. ÁíÒ»¸öÂýµÄÔÒòÔÚÓÚ±àÒëÆ÷¿ÉÄÜ»áÓÉÓÚº¯ÊýÄÚÖ´ÐеÄÈÎÎñµ¼ÖÂÎÞ·¨ÓÅ»¯.
(Èç¹ûº¯Êý´øÓи±×÷Óõϰ)
ÕâÖÖ»ùÓÚÊý×éµÄʵÏÖ, ȱÏÝÔÚÓÚº¯Êý±íÎÞ·¨ÍØÕ¹. ×ÓÀà»áÔÚÐéÊýº¯Êý±íµÄ×îºó²åÈëеĺ¯Êý, ûÓÐλÖÿÉÒÔÈÃ
extension °²È«µØ²åÈ뺯Êý. ÕâÆªÌá°¸ºÜÏêϸµØÃèÊöÁËÕâô×öµÄ¾ÖÏÞ.
ÏûÏ¢»úÖÆÅÉ·¢ (Message Dispatch )
ÏûÏ¢»úÖÆÊǵ÷Óú¯Êý×̬µÄ·½Ê½. Ò²ÊÇ Cocoa µÄ»ùʯ, ÕâÑùµÄ»úÖÆ´ßÉúÁË
KVO, UIAppearence ºÍ CoreData µÈ¹¦ÄÜ. ÕâÖÖÔË×÷·½Ê½µÄ¹Ø¼üÔÚÓÚ¿ª·¢Õß¿ÉÒÔÔÚÔËÐÐʱ¸Ä±äº¯ÊýµÄÐÐΪ.
²»Ö¹¿ÉÒÔͨ¹ý swizzling À´¸Ä±ä, ÉõÖÁ¿ÉÒÔÓà isa-swizzling Ð޸ĶÔÏóµÄ¼Ì³Ð¹ØÏµ,
¿ÉÒÔÔÚÃæÏò¶ÔÏóµÄ»ù´¡ÉÏʵÏÖ×Ô¶¨ÒåÅÉ·¢.
¾Ù¸öÀý×Ó, ¿´¿´ÏÂÃæÁ½¸öÀà:
class ParentClass { dynamic func method1() {} dynamic func method2() {} } class ChildClass: ParentClass { override func method2() {} dynamic func method3() {} } |
Swift »áÓÃÊ÷À´¹¹½¨ÕâÖּ̳йØÏµ:

ÕâÕÅͼºÜºÃµØÕ¹Ê¾ÁË Swift ÈçºÎʹÓÃÊ÷À´¹¹½¨ÀàºÍ×ÓÀà.
µ±Ò»¸öÏûÏ¢±»ÅÉ·¢, ÔËÐÐʱ»á˳×ÅÀàµÄ¼Ì³Ð¹ØÏµÏòÉϲéÕÒÓ¦¸Ã±»µ÷Óõĺ¯Êý. Èç¹ûÄã¾õµÃÕâÑù×öЧÂʺܵÍ, ËüȷʵºÜµÍ!
È»¶ø, Ö»Òª»º´æ½¨Á¢ÁËÆðÀ´, Õâ¸ö²éÕÒ¹ý³Ì¾Í»áͨ¹ý»º´æÀ´°ÑÐÔÄÜÌá¸ßµ½ºÍº¯Êý±íÅÉ·¢Ò»Ñù¿ì. µ«ÕâÖ»ÊÇÏûÏ¢»úÖÆµÄÔÀí,
ÕâÀïÓÐһƪÎÄÕºÜÉîÈëµÄ½²½âÁ˾ßÌåµÄ¼¼Êõϸ½Ú.
Swift µÄÅÉ·¢»úÖÆ
ÄÇô, µ½µ× Swift ÊÇÔõôÅÉ·¢µÄÄØ? ÎÒûÄÜÕÒµ½Ò»¸öºÜ¼òÃ÷¶óÒªµÄ´ð°¸, µ«ÕâÀïÓÐËĸöÑ¡Ôñ¾ßÌåÅÉ·¢·½Ê½µÄÒòËØ´æÔÚ:
ÉùÃ÷µÄλÖÃ
ÒýÓÃÀàÐÍ
ÌØ¶¨µÄÐÐΪ
ÏÔʽµØÓÅ»¯(Visibility Optimizations)
ÔÚ½âÊÍÕâЩÒòËØÖ®Ç°, ÎÒÓбØÒªËµÇå³þ, Swift ûÓÐÔÚÎĵµÀï¾ßÌåдÃ÷ʲôʱºò»áʹÓú¯Êý±íʲôʱºòʹÓÃÏûÏ¢»úÖÆ.
ΨһµÄ³ÐŵÊÇʹÓà dynamic ÐÞÊεÄʱºò»áͨ¹ý Objective-C µÄÔËÐÐʱ½øÐÐÏûÏ¢»úÖÆÅÉ·¢.
ÏÂÃæÎÒдµÄËùÓж«Î÷, ¶¼Ö»ÊÇÎÒÔÚ Swift 3.0 Àï²âÊÔ³öÀ´µÄ½á¹û, ²¢ÇҺܿÉÄÜÔÚÖ®ºóµÄ°æ±¾¸üÐÂÀï½øÐÐÐÞ¸Ä.
ÉùÃ÷µÄλÖà (Location Matters)
ÔÚ Swift Àï, Ò»¸öº¯ÊýÓÐÁ½¸ö¿ÉÒÔÉùÃ÷µÄλÖÃ: ÀàÐÍÉùÃ÷µÄ×÷ÓÃÓò, ºÍ extension. ¸ù¾ÝÉùÃ÷ÀàÐ͵IJ»Í¬,
Ò²»áÓв»Í¬µÄÅÉ·¢·½Ê½.
class MyClass { func mainMethod() {} } extension MyClass { func extensionMethod() {} } |
ÉÏÃæµÄÀý×ÓÀï, mainMethod »áʹÓú¯Êý±íÅÉ·¢, ¶ø extensionMethod
Ôò»áʹÓÃÖ±½ÓÅÉ·¢. µ±ÎÒµÚÒ»´Î·¢ÏÖÕâ¼þÊÂÇéµÄʱºò¾õµÃºÜÒâÍâ, Ö±¾õÉÏÕâÁ½¸öº¯ÊýµÄÉùÃ÷·½Ê½²¢Ã»ÓÐÄÇô´óµÄ²îÒì.
ÏÂÃæÊÇÎÒ¸ù¾ÝÀàÐÍ, ÉùÃ÷λÖÃ×ܽá³öÀ´µÄº¯ÊýÅÉ·¢·½Ê½µÄ±í¸ñ.

ÕâÕűí¸ñչʾÁËĬÈÏÇé¿öÏ Swift ʹÓõÄÅÉ·¢·½Ê½.
×ܽáÆðÀ´ÓÐÕâô¼¸µã:
1.ÖµÀàÐÍ×ÜÊÇ»áʹÓÃÖ±½ÓÅÉ·¢, ¼òµ¥Ò×¶®
2.¶øÐÒéºÍÀàµÄ extension ¶¼»áʹÓÃÖ±½ÓÅÉ·¢
3.NSObject µÄ extension »áʹÓÃÏûÏ¢»úÖÆ½øÐÐÅÉ·¢
4.NSObject ÉùÃ÷×÷ÓÃÓòÀïµÄº¯Êý¶¼»áʹÓú¯Êý±í½øÐÐÅÉ·¢.
5.ÐÒéÀïÉùÃ÷µÄ, ²¢ÇÒ´øÓÐĬÈÏʵÏֵĺ¯Êý»áʹÓú¯Êý±í½øÐÐÅÉ·¢
ÒýÓÃÀàÐÍ (Reference Type Matters)
ÒýÓõÄÀàÐ;ö¶¨ÁËÅÉ·¢µÄ·½Ê½. ÕâºÜÏÔ¶øÒ×¼û, µ«Ò²ÊǾö¶¨ÐԵIJîÒì. Ò»¸ö±È½Ï³£¼ûµÄÒÉ»ó, ·¢ÉúÔÚÒ»¸öÐÒéÍØÕ¹ºÍÀàÐÍÍØÕ¹Í¬Ê±ÊµÏÖÁËͬһ¸öº¯ÊýµÄʱºò.
protocol MyProtocol { } struct MyStruct: MyProtocol { } extension MyStruct { func extensionMethod() { print("½á¹¹Ìå") } } extension MyProtocol { func extensionMethod() { print("ÐÒé") } } let myStruct = MyStruct() let proto: MyProtocol = myStruct myStruct.extensionMethod() // -> ¡°½á¹¹Ì塱 proto.extensionMethod() // -> ¡°ÐÒ顱 |
¸Õ½Ó´¥ Swift µÄÈË¿ÉÄÜ»áÈÏΪ proto.extensionMethod() µ÷ÓõÄÊǽṹÌåÀïµÄʵÏÖ.
µ«ÊÇ, ÒýÓõÄÀàÐ;ö¶¨ÁËÅÉ·¢µÄ·½Ê½, ÐÒéÍØÕ¹ÀïµÄº¯Êý»áʹÓÃÖ±½Óµ÷ÓÃ. Èç¹û°Ñ extensionMethod
µÄÉùÃ÷ÒÆ¶¯µ½ÐÒéµÄÉùÃ÷λÖõϰ, Ôò»áʹÓú¯Êý±íÅÉ·¢, ×îÖվͻáµ÷ÓýṹÌåÀïµÄʵÏÖ. ²¢ÇÒÒª¼ÇµÃ, Èç¹ûÁ½ÖÖÉùÃ÷·½Ê½¶¼Ê¹ÓÃÁËÖ±½ÓÅÉ·¢µÄ»°,
»ùÓÚÖ±½ÓÅÉ·¢µÄÔË×÷·½Ê½, ÎÒÃDz»¿ÉÄÜʵÏÖÔ¤ÏëµÄ override ÐÐΪ. Õâ¶ÔÓںܶà´Ó Objective-C
¹ý¶É¹ýÀ´µÄ¿ª·¢ÕßÊÇ·´Ö±¾õµÄ.
Swift JIRA(ȱÏݸú×Ù¹ÜÀíϵͳ) Ò²·¢ÏÖÁ˼¸¸ö bugs, Swfit-Evolution ÓʼþÁбíÀïÓÐÒ»´ó¶ÑÌÖÂÛ,
Ò²ÓÐÒ»´ó¶Ñ²©¿ÍÌÖÂÛ¹ýÕâ¸ö. µ«ÊÇ, ÕâºÃÏñÊǹÊÒâÕâô×öµÄ, ËäÈ»¹Ù·½ÎĵµÃ»ÓÐÌá¹ýÕâ¼þÊÂÇé
Ö¸¶¨ÅÉ·¢·½Ê½ (Specifying Dispatch Behavior)
Swift ÓÐһЩÐÞÊηû¿ÉÒÔÖ¸¶¨ÅÉ·¢·½Ê½.
final
final ÔÊÐíÀàÀïÃæµÄº¯ÊýʹÓÃÖ±½ÓÅÉ·¢. Õâ¸öÐÞÊηû»áÈú¯Êýʧȥ¶¯Ì¬ÐÔ. Èκκ¯Êý¶¼¿ÉÒÔʹÓÃÕâ¸öÐÞÊηû,
¾ÍËãÊÇ extension Àï±¾À´¾ÍÊÇÖ±½ÓÅÉ·¢µÄº¯Êý. ÕâÒ²»áÈà Objective-C µÄÔËÐÐʱ»ñÈ¡²»µ½Õâ¸öº¯Êý,
²»»áÉú³ÉÏàÓ¦µÄ selector.
dynamic
dynamic ¿ÉÒÔÈÃÀàÀïÃæµÄº¯ÊýʹÓÃÏûÏ¢»úÖÆÅÉ·¢. ʹÓà dynamic, ±ØÐëµ¼Èë Foundation
¿ò¼Ü, ÀïÃæ°üÀ¨ÁË NSObject ºÍ Objective-C µÄÔËÐÐʱ. dynamic ¿ÉÒÔÈÃÉùÃ÷ÔÚ
extension ÀïÃæµÄº¯ÊýÄܹ»±» override. dynamic ¿ÉÒÔÓÃÔÚËùÓÐ NSObject
µÄ×ÓÀàºÍ Swift µÄÔÉùÀà.
@objc & @nonobjc
@objc ºÍ @nonobjc ÏÔʽµØÉùÃ÷ÁËÒ»¸öº¯ÊýÊÇ·ñÄܱ» Objective-C µÄÔËÐÐʱ²¶»ñµ½.
ʹÓà @objc µÄµäÐÍÀý×Ó¾ÍÊǸø selector Ò»¸öÃüÃû¿Õ¼ä @objc(abc_methodName),
ÈÃÕâ¸öº¯Êý¿ÉÒÔ±» Objective-C µÄÔËÐÐʱµ÷ÓÃ. @nonobjc »á¸Ä±äÅÉ·¢µÄ·½Ê½, ¿ÉÒÔÓÃÀ´½ûÖ¹ÏûÏ¢»úÖÆÅÉ·¢Õâ¸öº¯Êý,
²»ÈÃÕâ¸öº¯Êý×¢²áµ½ Objective-C µÄÔËÐÐʱÀï. ÎÒ²»È·¶¨Õâ¸ú final ÓÐÊ²Ã´Çø±ð, ÒòΪ´ÓʹÓó¡¾°À´ËµÒ²¼¸ºõÒ»Ñù.
ÎÒ¸öÈËÀ´Ëµ¸üϲ»¶ final, ÒòΪÒâͼ¸ü¼ÓÃ÷ÏÔ.
ÒëÕß×¢: ÎÒ¸öÈ˸оõ, ÕâÕâÖ÷ÒªÊÇΪÁ˸ú Objective-C ¼æÈÝÓõÄ, final µÈÔÉú¹Ø¼ü´Ê,
ÊÇÈà Swift д·þÎñ¶ËÖ®ÀàµÄ´úÂëµÄʱºò¿ÉÒÔÓÐÔÉúµÄ¹Ø¼ü´Ê¿ÉÒÔʹÓÃ.
final @objc
¿ÉÒÔÔÚ±ê¼ÇΪ final µÄͬʱ, ҲʹÓà @objc À´Èú¯Êý¿ÉÒÔʹÓÃÏûÏ¢»úÖÆÅÉ·¢. Õâô×öµÄ½á¹û¾ÍÊÇ,
µ÷Óú¯ÊýµÄʱºò»áʹÓÃÖ±½ÓÅÉ·¢, µ«Ò²»áÔÚ Objective-C µÄÔËÐÐʱÀï×¢²áÏìÓ¦µÄ selector.
º¯Êý¿ÉÒÔÏìÓ¦ perform(selector:) ÒÔ¼°±ðµÄ Objective-C ÌØÐÔ, µ«ÔÚÖ±½Óµ÷ÓÃʱÓÖ¿ÉÒÔÓÐÖ±½ÓÅÉ·¢µÄÐÔÄÜ.
@inline
Swift Ò²Ö§³Ö @inline, ¸æËß±àÒëÆ÷¿ÉÒÔʹÓÃÖ±½ÓÅÉ·¢. ÓÐȤµÄÊÇ, dynamic @inline(__always)
func dynamicOrDirect() {} Ò²¿ÉÒÔͨ¹ý±àÒë! µ«ÕâÒ²Ö»ÊǸæËßÁ˱àÒëÆ÷¶øÒÑ, ʵ¼ÊÉÏÕâ¸öº¯Êý»¹ÊÇ»áʹÓÃÏûÏ¢»úÖÆÅÉ·¢.
ÕâÑùµÄд·¨¿´ÆðÀ´ÏñÊÇÒ»¸ö䶨ÒåµÄÐÐΪ, Ó¦¸Ã±ÜÃâÕâô×ö.
ÐÞÊηû×ܽá (Modifier Overview)

ÕâÕÅͼ×ܽáÕâЩÐÞÊηû¶ÔÓÚ Swift ÅÉ·¢·½Ê½µÄÓ°Ïì.
Èç¹ûÄãÏë²é¿´ÉÏÃæËùÓÐÀý×ӵϰ, Çë¿´ÕâÀï.
¿É¼ûµÄ¶¼»á±»ÓÅ»¯ (Visibility Will Optimize)
Swift »á¾¡×î´óÄÜÁ¦È¥ÓÅ»¯º¯ÊýÅÉ·¢µÄ·½Ê½. ÀýÈç, Èç¹ûÄãÓÐÒ»¸öº¯Êý´ÓÀ´Ã»ÓÐ override,
Swift ¾Í»á¼ì³µ²¢ÇÒÔÚ¿ÉÄܵÄÇé¿öÏÂʹÓÃÖ±½ÓÅÉ·¢. Õâ¸öÓÅ»¯´ó¶àÊýÇé¿ö϶¼±íÏֵúܺÃ, µ«¶ÔÓÚʹÓÃÁË
target / action ģʽµÄ Cocoa ¿ª·¢Õ߾Ͳ»ÄÇôÓѺÃÁË. ÀýÈç:
override func viewDidLoad() { super.viewDidLoad() navigationItem.rightBarButtonItem = UIBarButtonItem( title: "怬", style: .plain, target: nil, action: #selector(ViewController.signInAction) ) } private func signInAction() {} |
ÕâÀï±àÒëÆ÷»áÅ׳öÒ»¸ö´íÎó: Argument of '#selector' refers to a method
that is not exposed to Objective-C (Objective-C ÎÞ·¨»ñÈ¡
#selector Ö¸¶¨µÄº¯Êý). ÄãÈç¹û¼ÇµÃ Swift »á°ÑÕâ¸öº¯ÊýÓÅ»¯ÎªÖ±½ÓÅÉ·¢µÄ»°, ¾ÍÄÜÀí½âÕâ¼þÊÂÇéÁË.
ÕâÀïÐÞ¸´µÄ·½Ê½ºÜ¼òµ¥: ¼ÓÉÏ@objc »òÕß dynamic ¾Í¿ÉÒÔ±£Ö¤ Objective-C µÄÔËÐÐʱ¿ÉÒÔ»ñÈ¡µ½º¯ÊýÁË.
ÕâÖÖÀàÐ͵ĴíÎóÒ²»á·¢ÉúÔÚUIAppearance ÉÏ, ÒÀÀµÓÚ proxy ºÍ NSInvocation
µÄ´úÂë.
ÁíÒ»¸öÐèҪעÒâµÄÊÇ, Èç¹ûÄãûÓÐʹÓà dynamic ÐÞÊεϰ, Õâ¸öÓÅ»¯»áĬÈÏÈà KVO ʧЧ. Èç¹ûÒ»¸öÊôÐÔ°ó¶¨ÁË
KVO µÄ»°, ¶øÕâ¸öÊôÐ﵀ getter ºÍ setter »á±»ÓÅ»¯ÎªÖ±½ÓÅÉ·¢, ´úÂëÒÀ¾É¿ÉÒÔͨ¹ý±àÒë,
²»¹ý¶¯Ì¬Éú³ÉµÄ KVO º¯Êý¾Í²»»á±»´¥·¢.
Swift µÄ²©¿ÍÓÐһƪºÜÔÞµÄÎÄÕÂÃèÊöÁËÏà¹ØµÄϸ½Ú, ºÍÕâЩÓÅ»¯±³ºóµÄ¿¼ÂÇ.
ÅÉ·¢×ܽá (Dispatch Summary)
ÕâÀïÓÐÒ»´ó¶Ñ¹æÔòÒª¼Çס, ËùÒÔÎÒÕûÀíÁËÒ»¸ö±í¸ñ:

ÕâÕűí×ܽáÒýÓÃÀàÐÍ, ÐÞÊηûºÍËüÃǶÔÓÚ Swift º¯ÊýÅÉ·¢µÄÓ°Ïì
NSObject ÒÔ¼°¶¯Ì¬ÐÔµÄËðʧ (NSObject and the
Loss of Dynamic Behavior)
²»¾Ã֮ǰ»¹ÓÐһȺ Cocoa ¿ª·¢ÕßÌÖÂÛ¶¯Ì¬ÐÐΪ´øÀ´µÄÎÊÌâ. Õâ¶ÎÌÖÂÛºÜÓÐȤ, ÌáÁËÒ»´ó¶Ñ²»Í¬µÄ¹Ûµã.
ÎÒÏ£Íû¿ÉÒÔÔÚÕâÀï¼ÌÐøÌ½ÌÖÒ»ÏÂ, Óм¸¸ö Swift µÄÅÉ·¢·½Ê½ÎÒ¾õµÃËðº¦Á˶¯Ì¬ÐÔ, ˳±ã˵һÏÂÎҵĽâ¾ö·½°¸.
NSObject µÄº¯Êý±íÅÉ·¢ (Table Dispatch in
NSObject)
ÉÏÃæ, ÎÒÌáµ½ NSObject ×ÓÀඨÒåÀïµÄº¯Êý»áʹÓú¯Êý±íÅÉ·¢. µ«ÎÒ¾õµÃºÜÃÔ»ó, ºÜÄѽâÊÍÇå³þ,
²¢ÇÒÓÉÓÚÏÂÃæ¼¸¸öÔÒò, ÕâÒ²Ö»´øÀ´ÁËÒ»µãµãÐÔÄܵÄÌáÉý:
´ó²¿·Ö NSObject µÄ×ÓÀà¶¼ÊÇÔÚ obj_msgSend µÄ»ù´¡ÉϹ¹½¨µÄ. ÎҺܻ³ÒÉÕâЩÅÉ·¢·½Ê½µÄÓÅ»¯,
ʵ¼Êµ½µ×»á¸ø Cocoa µÄ×ÓÀà´øÀ´¶à´óµÄÌáÉý.
´ó¶àÊý Swift µÄ NSObject ×ÓÀà¶¼»áʹÓà extension ½øÐÐÍØÕ¹, ¶¼Ã»°ì·¨Ê¹ÓÃÕâÖÖÓÅ»¯.
×îºó, ÓÐһЩСϸ½Ú»áÈÃÅÉ·¢·½Ê½±äµÃºÜ¸´ÔÓ.
ÅÉ·¢·½Ê½µÄÓÅ»¯ÆÆ»µÁË NSObject µÄ¹¦ÄÜ (Dispatch Upgrades
Breaking NSObject Features)
ÐÔÄÜÌáÉýºÜ°ô, ÎÒºÜϲ»¶ Swift ¶ÔÓÚÅÉ·¢·½Ê½µÄÓÅ»¯. µ«ÊÇ, UIView ×ÓÀàÑÕÉ«µÄÊôÐÔÀíÂÛÉÏÐÔÄܵÄÌáÉýÆÆ»µÁË
UIKit ÏÖÓеÄģʽ.
ÔÎÄ: However, having a theoretical performance boost
in my UIView subclass color property breaking an established
pattern in UIKit is damaging to the language.
NSObject ×÷Ϊһ¸öÑ¡Ôñ (NSObject as a Choice)
ʹÓþ²Ì¬ÅÉ·¢µÄ»°½á¹¹ÌåÊǸö²»´íµÄÑ¡Ôñ, ¶øÊ¹ÓÃÏûÏ¢»úÖÆÅÉ·¢µÄ»°Ôò¿ÉÒÔ¿¼ÂÇ NSObject. ÏÖÔÚ,
Èç¹ûÄãÏë¸úÒ»¸ö¸Õѧ Swift µÄ¿ª·¢Õß½âÊÍΪʲôij¸ö¶«Î÷ÊÇÒ»¸ö NSObject µÄ×ÓÀà, Äã²»µÃ²»È¥½éÉÜ
Objective-C ÒÔ¼°Õâ¶ÎÀúÊ·. ÏÖÔÚûÓÐÈκÎÀíÓÉÈ¥¼Ì³Ð NSObject ¹¹½¨Àà, ³ý·ÇÄãÐèҪʹÓÃ
Objective-C ¹¹½¨µÄ¿ò¼Ü.
Ŀǰ, NSObject ÔÚ Swift ÀïµÄÅÉ·¢·½Ê½, Ò»¾ä»°×ܽá¾ÍÊǸ´ÔÓ, ¸úÀíÏ뻹ÊÇÓвî¾à. ÎұȽÏÏë¿´µ½Õâ¸öÐÞ¸Ä:
µ±Äã¼Ì³Ð NSObject µÄʱºò, ÕâÊÇÒ»¸öÄãÏëÒªÍêȫʹÓö¯Ì¬ÏûÏ¢»úÖÆµÄ±íÏÖ.
ÏÔʽµÄ¶¯Ì¬ÐÔÉùÃ÷ (Implicit Dynamic Modification)
ÁíÒ»¸ö Swift ¿ÉÒԸĽøµÄµØ·½¾ÍÊǺ¯Êý¶¯Ì¬ÐԵļì²â. ÎÒ¾õµÃÔÚ¼ì²âµ½Ò»¸öº¯Êý±» #selector
ºÍ #keypath ÒýÓÃʱҪ×Ô¶¯°ÑÕâЩº¯Êý±ê¼ÇΪ dynamic, ÕâÑùµÄ»°¾Í»á½â¾ö´ó²¿·Ö UIAppearance
µÄ¶¯Ì¬ÎÊÌâ, µ«Ò²ÐíÓбðµÄ±àÒëʱµÄ´¦Àí·½Ê½¿ÉÒÔ±ê¼ÇÕâЩº¯Êý.
Error ÒÔ¼° Bug (Errors and Bugs)
ΪÁËÈÃÎÒÃÇ¶Ô Swift µÄÅÉ·¢·½Ê½Óиü¶àÁ˽â, ÈÃÎÒÃÇÀ´¿´Ò»Ï Swift ¿ª·¢ÕßÓöµ½¹ýµÄ error.
SR-584
Õâ¸ö Swift bug ÊÇ Swift º¯ÊýÅÉ·¢µÄÒ»¸ö¹¦ÄÜ. ´æÔÚÓÚ NSObject ×ÓÀàÉùÃ÷µÄº¯Êý(º¯Êý±íÅÉ·¢),
ÒÔ¼°ÉùÃ÷ÔÚ extension µÄº¯Êý(ÏûÏ¢»úÖÆÅÉ·¢)ÖÐ. ΪÁ˸üºÃµØÃèÊöÕâ¸öÇé¿ö, ÎÒÃÇÏÈÀ´´´½¨Ò»¸öÀà:
class Person: NSObject { func sayHi() { print("Hello") } } func greetings(person: Person) { person.sayHi() } greetings(person: Person()) // prints 'Hello' |
greetings(person:) º¯ÊýʹÓú¯Êý±íÅÉ·¢À´µ÷Óà sayHi(). ¾ÍÏñÎÒÃÇ¿´µ½µÄ, ÆÚÍûµÄ,
¡°Hello¡± »á±»´òÓ¡. ûʲôºÃ½²µÄµØ·½, ÄÇÏÖÔÚÈÃÎÒÃǼ̳РPersion:
class MisunderstoodPerson: Person {} extension MisunderstoodPerson { override func sayHi() { print("No one gets me.") } } greetings(person: MisunderstoodPerson()) // prints 'Hello' |
¿ÉÒÔ¿´µ½, sayHi() º¯ÊýÊÇÔÚ extension ÀïÉùÃ÷µÄ, »áʹÓÃÏûÏ¢»úÖÆ½øÐе÷ÓÃ. µ±greetings(person:)
±»´¥·¢Ê±, sayHi() »áͨ¹ýº¯Êý±í±»ÅÉ·¢µ½ Person ¶ÔÏó, ¶ømisunderstoodPerson
ÖØÐ´Ö®ºó»áÊÇÓÃÏûÏ¢»úÖÆ, ¶ø MisunderstoodPerson µÄº¯Êý±íÒÀ¾É±£ÁôÁË Person
µÄʵÏÖ, ½ô½Ó×ÅÆçÒå¾Í²úÉúÁË.
ÔÚÕâÀïµÄ½â¾ö·½·¨ÊDZ£Ö¤º¯ÊýʹÓÃÏàͬµÄÏûÏ¢ÅÉ·¢»úÖÆ. Äã¿ÉÒÔ¸øº¯Êý¼ÓÉÏ dynamic ÐÞÊηû, »òÕßÊǰѺ¯ÊýµÄʵÏÖ´Ó
extension ÒÆ¶¯µ½Àà×î³õÉùÃ÷µÄ×÷ÓÃÓòÀï.
Àí½âÁË Swift µÄÅÉ·¢·½Ê½, ¾ÍÄܹ»Àí½âÕâ¸öÐÐΪ²úÉúµÄÔÒòÁË, ËäÈ» Swift ²»Ó¦¸ÃÈÃÎÒÃÇÓöµ½Õâ¸öÎÊÌâ.
SR-103
Õâ¸ö Swift bug ´¥·¢Á˶¨ÒåÔÚÐÒéÍØÕ¹µÄĬÈÏʵÏÖ, ¼´Ê¹ÊÇ×ÓÀàÒѾʵÏÖÕâ¸öº¯ÊýµÄÇé¿öÏÂ. ΪÁË˵Ã÷Õâ¸öÎÊÌâ,
ÎÒÃÇÏȶ¨ÒåÒ»¸öÐÒé, ²¢ÇÒ¸øÀïÃæµÄº¯ÊýÒ»¸öĬÈÏʵÏÖ:
protocol Greetable { func sayHi() } extension Greetable { func sayHi() { print("Hello") } } func greetings(greeter: Greetable) { greeter.sayHi() } |
ÏÖÔÚ, ÈÃÎÒÃǶ¨ÒåÒ»¸ö×ñÊØÁËÕâ¸öÐÒéµÄÀà. Ïȶ¨ÒåÒ»¸ö Person Àà, ×ñÊØ Greetable ÐÒé,
È»ºó¶¨ÒåÒ»¸ö×ÓÀà LoudPerson, ÖØÐ´sayHi() ·½·¨.
class Person: Greetable { } class LoudPerson: Person { func sayHi() { print("HELLO") } } |
ÄãÃÇ·¢ÏÖ LoudPerson ʵÏֵĺ¯ÊýÇ°ÃæÃ»ÓÐ override ÐÞÊÎ, ÕâÊÇÒ»¸öÌáʾ, Ò²Ðí´úÂë²»»áÏñÎÒÃÇÉèÏëµÄÄÇÑùÔËÐÐ.
ÔÚÕâ¸öÀý×ÓÀï,LoudPerson ûÓÐÔÚ Greetable µÄÐÒé¼Ç¼±í(Protocol Witness
Table)Àï³É¹¦×¢²á, µ± sayHi() ͨ¹ý Greetable ÐÒéÅÉ·¢Ê±, ĬÈϵÄʵÏ־ͻᱻµ÷ÓÃ.
½â¾öµÄ·½·¨¾ÍÊÇ, ÔÚÀàÉùÃ÷µÄ×÷ÓÃÓòÀï¾ÍÒªÌṩËùÓÐÐÒéÀﶨÒåµÄº¯Êý, ¼´Ê¹ÒѾÓÐĬÈÏʵÏÖ. »òÕß, Äã¿ÉÒÔÔÚÀàµÄÇ°Ãæ¼ÓÉÏÒ»¸öfinal
ÐÞÊηû, ±£Ö¤Õâ¸öÀ಻»á±»¼Ì³Ð.
Doug Gregor ÔÚ Swift-Evolution ÓʼþÁбíÀïÌáµ½, ͨ¹ýÏÔʽµØÖØÐ°Ѻ¯ÊýÉùÃ÷ΪÀàµÄº¯Êý,
¾Í¿ÉÒÔ½â¾öÕâ¸öÎÊÌâ, ²¢ÇÒ²»»áÆ«ÀëÎÒÃǵÄÉèÏë.
ÆäËü bug (Other bugs)
Another bug that I thought I¡¯d mention is SR-435. It
involves two protocol extensions, where one extension
is more specific than the other. The example in the
bug shows one un-constrained extension, and one extension
that is constrained to Equatable types. When the method
is invoked inside a protocol, the more specific method
is not called. I¡¯m not sure if this always occurs or
not, but seems important to keep an eye on.
ÁíÍâÒ»¸ö bug ÎÒÔÚ SR-435 ÀïÒѾÌá¹ýÁË. µ±ÓÐÁ½¸öÐÒéÍØÕ¹, ¶øÆäÖÐÒ»¸ö¸ü¼Ó¾ßÌåʱ¾Í»á´¥·¢.
ÀýÈç, ÓÐÒ»¸ö²»ÊÜÔ¼ÊøµÄ extension, ¶øÁíÒ»¸ö±» Equatable Ô¼Êø, µ±Õâ¸ö·½·¨Í¨¹ýÐÒéÅÉ·¢,
Ô¼Êø±È½Ï¶àµÄÄǸö extension µÄʵÏÖÔò²»»á±»µ÷ÓÃ. ÎÒ²»Ì«È·¶¨ÕâÊDz»ÊǰٷÖÖ®°ÙÄܸ´ÏÖ, µ«ÓбØÒªÁô¸öÐÄÑÛ.
If you are aware of any other Swift dispatch bugs,
drop me a line and I¡¯ll update this blog post.
Èç¹ûÄã·¢ÏÖÁËÆäËü Swift ÅÉ·¢µÄ bug µÄ»°, @Ò»ÏÂÎÒÎҾͻá¸üе½ÕâÆª²©¿ÍÀï.
ÓÐȤµÄ Error (Interesting Error)
ÓÐÒ»¸öºÜºÃÍæµÄ±àÒë´íÎó, ¿ÉÒÔ¿ú¼ûµ½ Swift µÄ¼Æ»®. ¾ÍÏñ֮ǰ˵µÄ, ÀàÍØÕ¹Ê¹ÓÃÖ±½ÓÅÉ·¢, ËùÒÔÄãÊÔͼ
override Ò»¸öÉùÃ÷ÔÚ extension ÀïµÄº¯ÊýµÄʱºò»á·¢Éúʲô?
class MyClass { } extension MyClass { func extensionMethod() {} } class SubClass: MyClass { override func extensionMethod() {} } |
ÉÏÃæµÄ´úÂë»á´¥·¢Ò»¸ö±àÒë´íÎó Declarations in extensions can not be
overridden yet(ÉùÃ÷ÔÚ extension ÀïµÄ·½·¨²»¿ÉÒÔ±»ÖØÐ´). Õâ¿ÉÄÜÊÇ Swift
ÍŶӴòËã¼ÓÇ¿º¯Êý±íÅÉ·¢µÄÒ»¸öÕ÷Õ×. ÓÖ»òÕßÕâÖ»ÊÇÎÒ¹ý¶È½â¶Á, ¾õµÃÕâÃÅÓïÑÔ¿ÉÒÔÓÅ»¯µÄµØ·½.
ÖÂл Thanks
ÎÒÏ£ÍûÁ˽⺯ÊýÅÉ·¢»úÖÆµÄ¹ý³ÌÖÐÄã¸ÐÊܵ½ÁËÀÖȤ, ²¢ÇÒ¿ÉÒÔ°ïÖúÄã¸üºÃµÄÀí½â Swift. ËäÈ»ÎÒ±§Ô¹ÁË
NSObject Ïà¹ØµÄһЩ¶«Î÷, µ«ÎÒ»¹ÊǾõµÃ Swift ÌṩÁ˸ßÐÔÄܵĿÉÄÜÐÔ, ÎÒÖ»ÊÇÏ£Íû¿ÉÒÔÓÐ×ã¹»¼òµ¥µÄ·½Ê½,
ÈÃÕâÆª²©¿ÍûÓдæÔڵıØÒª. |