±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÃÀÍż¼ÊõÍŶÓ,ÏÂÃæÎÒÃǽ«´ÓÕâÁ½¸ö½Ç¶ÈÇÐÈ룬¶ÔSwiftÐÔÄÜÓÅ»¯½øÐзÖÎö¡£Í¨¹ýÁ˽â±àÒëÆ÷¶Ô²»Í¬Êý¾Ý½á¹¹´¦ÀíµÄÄÚ²¿ÊµÏÖ£¬À´Ñ¡Ôñ×îºÏÊʵÄËã·¨»úÖÆ£¬²¢ÀûÓñàÒëÆ÷µÄÓÅ»¯ÌØÐÔ£¬±àд¸ßÐÔÄܵijÌÐò¡£ |
|
¼ò½é
2014Ä꣬ƻ¹û¹«Ë¾ÔÚWWDCÉÏ·¢²¼SwiftÕâһеıà³ÌÓïÑÔ¡£¾¹ý¼¸ÄêµÄ·¢Õ¹£¬SwiftÒѾ³ÉΪiOS¿ª·¢ÓïÑԵġ°ÖÐÁ÷íÆÖù¡±£¬SwiftÌṩÁ˷dz£Áé»îµÄ¸ß¼¶±ðÌØÐÔ£¬ÀýÈçÐÒé¡¢±Õ°ü¡¢·ºÐ͵ȣ¬²¢ÇÒSwift»¹½øÒ»²½¿ª·¢ÁËÇ¿´óµÄSIL£¨Swift
Intermediate Language£©ÓÃÓÚ¶Ô±àÒëÆ÷½øÐÐÓÅ»¯£¬Ê¹µÃSwiftÏà±ÈObjective-CÔËÐиü¿ìÐÔÄܸüÓÅ£¬SwiftÄÚ²¿ÈçºÎʵÏÖÐÔÄܵÄÓÅ»¯£¬ÎÒÃDZ¾ÎľͽøÐÐһϽâ¶Á£¬Ï£ÍûÄܶԴó¼ÒÓÐËùÆô·¢ºÍ°ïÖú¡£
Õë¶ÔSwiftÐÔÄÜÌáÉýÕâÒ»ÎÊÌ⣬ÎÒÃÇ¿ÉÒÔ´Ó¸ÅÄîÉϲð·ÖΪÁ½¸ö²¿·Ö£º
±àÒëÆ÷£ºSwift±àÒëÆ÷½øÐеÄÐÔÄÜÓÅ»¯£¬´Ó½×¶Î·ÖΪ±àÒëÆÚºÍÔËÐÐÆÚ£¬ÄÚÈÝ·ÖΪʱ¼äÓÅ»¯ºÍ¿Õ¼äÓÅ»¯¡£
¿ª·¢ÕߣºÍ¨¹ýʹÓúÏÊʵÄÊý¾Ý½á¹¹ºÍ¹Ø¼ü×Ö£¬°ïÖú±àÒëÆ÷»ñÈ¡¸ü¶àÐÅÏ¢£¬½øÐÐÓÅ»¯¡£
Àí½âSwiftµÄÐÔÄÜ
Àí½âSwiftµÄÐÔÄÜ£¬Ê×ÏÈÒªÇå³þSwiftµÄÊý¾Ý½á¹¹£¬×é¼þ¹ØÏµºÍ±àÒëÔËÐз½Ê½¡£
Êý¾Ý½á¹¹
SwiftµÄÊý¾Ý½á¹¹¿ÉÒÔ´óÌå²ð·ÖΪ£ºClass£¬Struct£¬Enum¡£
×é¼þ¹ØÏµ
×é¼þ¹ØÏµ¿ÉÒÔ·ÖΪ£ºinheritance£¬protocols£¬generics¡£
·½·¨·ÖÅÉ·½Ê½
·½·¨·ÖÅÉ·½Ê½¿ÉÒÔ·ÖΪStatic dispatchºÍDynamic dispatch¡£
ÒªÔÚ¿ª·¢ÖÐÌá¸ßSwiftÐÔÄÜ£¬ÐèÒª¿ª·¢ÕßÈ¥Á˽âÕ⼸ÖÖÊý¾Ý½á¹¹ºÍ×é¼þ¹ØÏµÒÔ¼°ËüÃǵÄÄÚ²¿ÊµÏÖ£¬´Ó¶øÍ¨¹ýÑ¡Ôñ×îºÏÊʵijéÏó»úÖÆÀ´ÌáÉýÐÔÄÜ¡£
Ê×ÏÈÎÒÃǶÔÓÚÐÔÄܱê×¼½øÐÐÒ»¸ö¸ÅÄî³ÂÊö£¬ÐÔÄܱê×¼º¸ÇÈý¸ö±ê×¼£º

Allocation
Reference counting
Method dispatch
½ÓÏÂÀ´£¬ÎÒÃÇ»á·Ö±ð¶ÔÕ⼸¸öÖ¸±ê½øÐÐ˵Ã÷¡£
Allocation
ÄÚ´æ·ÖÅä¿ÉÒÔ·ÖΪ¶ÑÇøÕ»Çø£¬ÔÚÕ»µÄÄÚ´æ·ÖÅäËÙ¶ÈÒª¸ßÓÚ¶Ñ£¬½á¹¹ÌåºÍÀàÔÚ¶ÑÕ»·ÖÅäÊDz»Í¬µÄ¡£
Stack
»ù±¾Êý¾ÝÀàÐͺͽṹÌåĬÈÏÔÚÕ»Çø£¬Õ»ÇøÄÚ´æÊÇÁ¬ÐøµÄ£¬Í¨¹ý³öÕ»ÈëÕ»½øÐзÖÅäºÍÏú»Ù£¬ËٶȺܿ죬¸ßÓÚ¶ÑÇø¡£
ÎÒÃÇͨ¹ýһЩÀý×Ó½øÐÐ˵Ã÷£º
//ʾÀý 1
// Allocation
// Struct
struct Point {
var x, y:Double
func draw() { ¡ }
}
let point1 = Point(x:0, y:0) //½øÐÐpoint1³õʼ»¯£¬¿ª±ÙÕ»ÄÚ´æ
var point2 = point1 //³õʼ»¯point2£¬¿½±´point1ÄÚÈÝ£¬¿ª±ÙÐÂÄÚ´æ
point2.x = 5 //¶Ôpoint2µÄ²Ù×÷²»»áÓ°Ïìpoint1
// use `point1`
// use `point2` |

ÒÔÉϽṹÌåµÄÄÚ´æÊÇÔÚÕ»Çø·ÖÅäµÄ£¬ÄÚ²¿µÄ±äÁ¿Ò²ÊÇÄÚÁªÔÚÕ»Çø¡£½«point1¸³Öµ¸øpoint2ʵ¼Ê²Ù×÷ÊÇÔÚÕ»Çø½øÐÐÁËÒ»·Ý¿½±´£¬²úÉúÁËеÄÄÚ´æÏûºÄpoint2£¬ÕâʹµÃpoint1ºÍpoint2ÊÇÍêÈ«¶ÀÁ¢µÄÁ½¸öʵÀý£¬ËüÃÇÖ®¼äµÄ²Ù×÷»¥²»Ó°Ïì¡£ÔÚʹÓÃpoint1ºÍpoint2Ö®ºó£¬»á½øÐÐÏú»Ù¡£
Heap
¸ß¼¶µÄÊý¾Ý½á¹¹£¬±ÈÈçÀ࣬·ÖÅäÔÚ¶ÑÇø¡£³õʼ»¯Ê±²éÕÒûÓÐʹÓõÄÄÚ´æ¿é£¬Ïú»ÙʱÔÙ´ÓÄÚ´æ¿éÖÐÇå³ý¡£ÒòΪ¶ÑÇø¿ÉÄÜ´æÔÚ¶àÏ̵߳IJÙ×÷ÎÊÌ⣬ΪÁ˱£Ö¤Ḭ̈߳²È«£¬ÐèÒª½øÐмÓËø²Ù×÷£¬Òò´ËÒ²ÊÇÒ»ÖÖÐÔÄÜÏûºÄ¡£
// Allocation
// Class
class Point {
var x, y:Double
func draw() { ¡ }
}
let point1 = Point(x:0, y:0) //ÔÚ¶ÑÇø·ÖÅäÄÚ´æ£¬Õ»ÇøÖ»ÊÇ´æ´¢µØÖ·Ö¸Õë
let point2 = point1 //²»²úÉúеÄʵÀý£¬¶øÊǶÔpoint2Ôö¼Ó¶Ô¶ÑÇøÄÚ´æÒýÓõÄÖ¸Õë
point2.x = 5 //ÒòΪpoint1ºÍpoint2ÊÇÒ»¸öʵÀý£¬ËùÒÔpoint1µÄÖµÒ²»á±»ÐÞ¸Ä
// use `point1`
// use `point2` |

ÒÔÉÏÎÒÃdzõʼ»¯ÁËÒ»¸öClassÀàÐÍ£¬ÔÚÕ»Çø·ÖÅäÒ»¿éÄڴ棬µ«ÊǺͽṹÌåÖ±½ÓÔÚÕ»ÄÚ´æ´¢ÊýÖµ²»Í¬£¬ÎÒÃÇÖ»ÔÚÕ»Çø´æ´¢Á˶ÔÏóµÄÖ¸Õ룬ָÕëÖ¸ÏòµÄ¶ÔÏóµÄÄÚ´æÊÇ·ÖÅäÔÚ¶ÑÇøµÄ¡£ÐèҪעÒâµÄÊÇ£¬ÎªÁ˹ÜÀí¶ÔÏóÄڴ棬ÔÚ¶ÑÇø³õʼ»¯Ê±£¬³ýÁË·ÖÅäÊôÐÔÄڴ棨ÕâÀïÊÇDoubleÀàÐ͵Äx£¬y£©£¬»¹»áÓжîÍâµÄÁ½¸ö×ֶΣ¬·Ö±ðÊÇtypeºÍrefCount£¬Õâ¸ö°üº¬ÁËtype£¬refCountºÍʵ¼ÊÊôÐԵĽṹ±»³ÆÎªblue
box¡£
ÄÚ´æ·ÖÅä×ܽá
´Ó³õʼ»¯½Ç¶È£¬ClassÏà±ÈStructÐèÒªÔÚ¶ÑÇø·ÖÅäÄڴ棬½øÐÐÄÚ´æ¹ÜÀí£¬Ê¹ÓÃÁËÖ¸Õ룬ÓиüÇ¿´óµÄÌØÐÔ£¬µ«ÊÇÐÔÄܽϵ͡£
ÓÅ»¯·½Ê½£º
¶ÔÓÚÆµ·±²Ù×÷£¨±ÈÈçͨÐÅÈí¼þµÄÄÚÈÝÆøÅÝչʾ£©£¬¾¡Á¿Ê¹ÓÃStructÌæ´úClass£¬ÒòΪջÄÚ´æ·ÖÅä¸ü¿ì£¬¸ü°²È«£¬²Ù×÷¸ü¿ì¡£
Reference counting
Swiftͨ¹ýÒýÓüÆÊý¹ÜÀí¶Ñ¶ÔÏóÄڴ棬µ±ÒýÓüÆÊýΪ0ʱ£¬SwiftÈ·ÈÏûÓжÔÏóÔÙÒýÓøÃÄڴ棬ËùÒÔ½«ÄÚ´æÊÍ·Å¡£¶ÔÓÚÒýÓüÆÊýµÄ¹ÜÀíÊÇÒ»¸ö·Ç³£¸ßƵµÄ¼ä½Ó²Ù×÷£¬²¢ÇÒÐèÒª¿¼ÂÇḬ̈߳²È«£¬Ê¹µÃÒýÓüÆÊýµÄ²Ù×÷ÐèÒª½Ï¸ßµÄÐÔÄÜÏûºÄ¡£
¶ÔÓÚ»ù±¾Êý¾ÝÀàÐ͵ÄStructÀ´Ëµ£¬Ã»ÓжÑÄÚ´æ·ÖÅäºÍÒýÓüÆÊýµÄ¹ÜÀí£¬ÐÔÄܸü¸ß¸ü°²È«£¬µ«ÊǶÔÓÚ¸´ÔӵĽṹÌ壬È磺
// Reference Counting
// Struct containing references
struct Label {
var text:String
var font:UIFont
func draw() { ¡ }
}
let label1 = Label(text:"Hi", font:font)
//Õ»Çø°üº¬ÁË´æ´¢ÔÚ¶ÑÇøµÄÖ¸Õë
let label2 = label1 //label2²úÉúеÄÖ¸Õ룬ºÍlabel1Ò»ÑùÖ¸ÏòͬÑùµÄstringºÍfontµØÖ·
// use `label1`
// use `label2` |

ÕâÀï¿´µ½£¬°üº¬ÁËÒýÓõĽṹÌåÏà±ÈClass£¬ÐèÒª¹ÜÀíË«±¶µÄÒýÓüÆÊý¡£Ã¿´Î½«½á¹¹Ìå×÷Ϊ²ÎÊý´«µÝ¸ø·½·¨»òÕß½øÐÐÖ±½Ó¿½±´Ê±£¬¶¼»á³öÏÖ¶à·ÝÒýÓüÆÊý¡£ÏÂͼ¿ÉÒԱȽÏÖ±¹ÛµÄÀí½â£º

±¸×¢£º°üº¬ÒýÓÃÀàÐ͵ĽṹÌå³öÏÖCopyµÄ´¦Àí·½Ê½
ClassÔÚ¿½±´Ê±µÄ´¦Àí·½Ê½£º

ÒýÓüÆÊý×ܽá
ClassÔÚ¶ÑÇø·ÖÅäÄڴ棬ÐèҪʹÓÃÒýÓüÆÊýÆ÷½øÐÐÄÚ´æ¹ÜÀí¡£
»ù±¾ÀàÐ͵ÄStructÔÚÕ»Çø·ÖÅäÄڴ棬ÎÞÒýÓüÆÊý¹ÜÀí¡£
°üº¬Ç¿ÀàÐ͵ÄStructͨ¹ýÖ¸Õë¹ÜÀíÔÚ¶ÑÇøµÄÊôÐÔ£¬¶Ô½á¹¹ÌåµÄ¿½±´»á´´½¨ÐµÄÕ»Äڴ棬´´½¨¶à·ÝÒýÓõÄÖ¸Õ룬ClassÖ»»áÓÐÒ»·Ý¡£
ÓÅ»¯·½Ê½
ÔÚʹÓýṹÌåʱ£º
ͨ¹ýʹÓþ«È·ÀàÐÍ£¬ÀýÈçUUIDÌæ´úString£¨UUID×Ö½Ú³¤¶È¹Ì¶¨128×Ö½Ú£¬¶ø²»ÊÇStringÈÎÒⳤ¶È£©£¬ÕâÑù¾Í¿ÉÒÔ½øÐÐÄÚ´æÄÚÁª£¬ÔÚÕ»ÄÚ´æ´¢UUID£¬ÎÒÃÇÖªµÀ£¬Õ»ÄÚ´æ¹ÜÀí¸ü¿ì¸ü°²È«£¬²¢ÇÒ²»ÐèÒªÒýÓüÆÊý¡£
EnumÌæ´úString£¬ÔÚÕ»ÄÚ¹ÜÀíÄڴ棬ÎÞÒýÓüÆÊý£¬²¢ÇÒ´ÓÓï·¨É϶ÔÓÚ¿ª·¢Õ߸üÓѺá£
Method Dispatch
ÎÒÃÇ֮ǰÔÚStatic dispatch VS Dynamic dispatchÖÐÌáµ½¹ý£¬Äܹ»ÔÚ±àÒëÆÚÈ·¶¨Ö´Ðз½·¨µÄ·½Ê½½Ð×ö¾²Ì¬·ÖÅÉStatic
dispatch£¬ÎÞ·¨ÔÚ±àÒëÆÚÈ·¶¨£¬Ö»ÄÜÔÚÔËÐÐʱȥȷ¶¨Ö´Ðз½·¨µÄ·ÖÅÉ·½Ê½½Ð×ö¶¯Ì¬·ÖÅÉDynamic
dispatch¡£
Static dispatch¸ü¿ì£¬¶øÇÒ¾²Ì¬·ÖÅÉ¿ÉÒÔ½øÐÐÄÚÁªµÈ½øÒ»²½µÄÓÅ»¯£¬Ê¹µÃÖ´Ðиü¿ìËÙ£¬ÐÔÄܸü¸ß¡£
µ«ÊǶÔÓÚ¶à̬µÄÇé¿ö£¬ÎÒÃDz»ÄÜÔÚ±àÒëÆÚÈ·¶¨×îÖÕµÄÀàÐÍ£¬ÕâÀï¾ÍÓõ½ÁËDynamic dispatch¶¯Ì¬·ÖÅÉ¡£¶¯Ì¬·ÖÅɵÄʵÏÖÊÇ£¬Ã¿ÖÖÀàÐͶ¼»á´´½¨Ò»ÕÅ±í£¬±íÄÚÊÇÒ»¸ö°üº¬ÁË·½·¨Ö¸ÕëµÄÊý×é¡£¶¯Ì¬·ÖÅɸüÁé»î£¬µ«ÊÇÒòΪÓвé±íºÍÌø×ªµÄ²Ù×÷£¬²¢ÇÒÒòΪºÜ¶àÌØµã¶ÔÓÚ±àÒëÆ÷À´Ëµ²¢²»Ã÷È·£¬ËùÒÔÏ൱ÓÚblockÁ˱àÒëÆ÷µÄһЩºóÆÚÓÅ»¯¡£ËùÒÔËÙ¶ÈÂýÓÚStatic
dispatch¡£
ÏÂÃæ¿´Ò»¶Î¶à̬´úÂ룬ÒÔ¼°·ÖÎöʵÏÖ·½Ê½£º
//ÒýÓÃÓïÒåʵÏֵĶà̬
class Drawable { func draw() {} }
class Point :Drawable {
var x, y:Double
override func draw() { ¡ }
}
class Line :Drawable {
var x1, y1, x2, y2:Double
override func draw() { ¡ }
}
var drawables:[Drawable]
for d in drawables {
d.draw£¨£©
} |

Method Dispatch×ܽá
ClassĬÈÏʹÓÃDynamic dispatch£¬ÒòΪÔÚ±àÒëÆÚ¼¸ºõÿ¸ö»·½ÚµÄÐÅÏ¢¶¼ÎÞ·¨È·¶¨£¬ËùÒÔ×è°Á˱àÒëÆ÷µÄÓÅ»¯£¬±ÈÈçinlineºÍwhole
module inline¡£
ʹÓÃStatic dispatch´úÌæDynamic dispatchÌáÉýÐÔÄÜ
ÎÒÃÇÖªµÀStatic dispatch¿ìÓÚDynamic dispatch£¬ÈçºÎÔÚ¿ª·¢ÖÐÈ¥¾¡¿ÉÄÜʹÓÃStatic
dispatch¡£
inheritance constraints¼Ì³ÐÔ¼Êø
ÎÒÃÇ¿ÉÒÔʹÓÃfinal¹Ø¼ü×ÖÈ¥ÐÞÊÎClass£¬ÒÔ´ËÉú³ÉµÄFinal class£¬Ê¹ÓÃStatic dispatch¡£
access control·ÃÎÊ¿ØÖÆ
private¹Ø¼ü×ÖÐÞÊΣ¬Ê¹µÃ·½·¨»òÊôÐÔÖ»¶Ôµ±Ç°Àà¿É¼û¡£±àÒëÆ÷»á¶Ô·½·¨½øÐÐStatic dispatch¡£
±àÒëÆ÷¿ÉÒÔͨ¹ýwhole module optimization¼ì²é¼Ì³Ð¹ØÏµ£¬¶ÔijЩûÓбê¼ÇfinalµÄÀàͨ¹ý¼ÆË㣬Èç¹ûÄÜÔÚ±àÒëÆÚÈ·¶¨Ö´Ðеķ½·¨£¬ÔòʹÓÃStatic
dispatch¡£
StructĬÈÏʹÓÃStatic dispatch¡£
Swift¿ìÓÚOCµÄÒ»¸ö¹Ø¼üÊÇ¿ÉÒÔÏû½â¶¯Ì¬·ÖÅÉ¡£
×ܽá
SwiftÌṩÁ˸üÁé»îµÄStruct£¬ÓÃÒÔÔÚÄÚ´æ¡¢ÒýÓüÆÊý¡¢·½·¨·ÖÅɵȽǶÈÈ¥½øÐÐÐÔÄܵÄÓÅ»¯£¬ÔÚÕýÈ·µÄʱ»úÑ¡ÔñÕýÈ·µÄÊý¾Ý½á¹¹£¬¿ÉÒÔʹÎÒÃǵĴúÂëÐÔÄܸü¿ì¸ü°²È«¡£
ÑÓÉì
Äã¿ÉÄÜ»áÎÊStructÈçºÎʵÏÖ¶àÌ¬ÄØ?´ð°¸ÊÇprotocol oriented programming¡£
ÒÔÉÏ·ÖÎöÁËÓ°ÏìÐÔÄܵö±ê×¼£¬ÄÇô²»Í¬µÄËã·¨»úÖÆClass£¬Protocol TypesºÍGeneric
code£¬ËüÃÇÔÚÕâÈý·½ÃæµÄ±íÏÖÈçºÎ£¬Protocol TypeºÍGeneric code·Ö±ðÊÇÔõôʵÏÖµÄÄØ£¿ÎÒÃÇ´ø×ÅÕâ¸öÎÊÌâ¿´ÏÂÈ¥¡£
Protocol Type
ÕâÀïÎÒÃÇ»áÌÖÂÛProtocol TypeÈçºÎ´æ´¢ºÍ¿½±´±äÁ¿£¬ÒÔ¼°·½·¨·ÖÅÉÊÇÈçºÎʵÏֵġ£²»Í¨¹ý¼Ì³Ð»òÕßÒýÓÃÓïÒåµÄ¶à̬£º
protocol Drawable
{ func draw() }
struct Point :Drawable {
var x, y:Double
func draw() { ¡ }
}
struct Line :Drawable {
var x1, y1, x2, y2:Double
func draw() { ¡ }
}
var drawables:[Drawable] //×ñÊØÁËDrawableÐÒéµÄÀàÐͼ¯ºÏ£¬¿ÉÄÜÊÇpoint»òÕßline
for d in drawables {
d.draw£¨£©
} |
ÒÔÉÏͨ¹ýProtocol TypeʵÏÖ¶à̬£¬¼¸¸öÀàÖ®¼äûÓм̳йØÏµ£¬¹Ê²»Äܰ´ÕÕ¹ßÀý½èÖúV-TableʵÏÖ¶¯Ì¬·ÖÅÉ¡£
Èç¹ûÏëÁ˽âVtableºÍWitness tableʵÏÖ£¬¿ÉÒÔ½øÐеã»÷²é¿´£¬ÕâÀï²»×öϸ½Ú˵Ã÷¡£
ÒòΪPointºÍLineµÄ³ß´ç²»Í¬£¬Êý×é´æ´¢Êý¾ÝʵÏÖÒ»ÖÂÐÔ´æ´¢£¬Ê¹ÓÃÁËExistential Container¡£²éÕÒÕýÈ·µÄÖ´Ðз½·¨ÔòʹÓÃÁË
Protoloc Witness Table ¡£

Existential Container
Existential ContainerÊÇÒ»ÖÖÌØÊâµÄÄÚ´æ²¼¾Ö·½Ê½£¬ÓÃÓÚ¹ÜÀí×ñÊØÁËÏàͬÐÒéµÄÊý¾ÝÀàÐÍProtocol
Type£¬ÕâЩÊý¾ÝÀàÐÍÒòΪ²»¹²Ïíͬһ¼Ì³Ð¹ØÏµ£¨ÕâÊÇV-TableʵÏÖµÄǰÌᣩ£¬²¢ÇÒÄÚ´æ¿Õ¼ä³ß´ç²»Í¬£¬Ê¹ÓÃExistential
Container½øÐйÜÀí£¬Ê¹Æä¾ßÓд洢µÄÒ»ÖÂÐÔ¡£

½á¹¹ÈçÏ£º
Èý¸ö´Ê´óСµÄvalueBuffer
ÕâÀï½éÉÜÒ»ÏÂvalueBuffer½á¹¹£¬valueBufferÓÐÈý¸ö´Ê£¬Ã¿¸ö´Ê°üº¬8¸ö×Ö½Ú£¬´æ´¢µÄ¿ÉÄÜÊÇÖµ£¬Ò²¿ÉÄÜÊǶÔÏóµÄÖ¸Õë¡£¶ÔÓÚsmall
value£¨¿Õ¼äСÓÚvalueBuffer£©£¬Ö±½Ó´æ´¢ÔÚvalueBufferµÄµØÖ·ÄÚ£¬ inline
valueBuffer£¬ÎÞ¶îÍâ¶ÑÄÚ´æ³õʼ»¯¡£µ±ÖµµÄÊýÁ¿´óÓÚ3¸öÊôÐÔ¼´large value£¬»òÕß×ܳߴ糬¹ývalueBufferµÄռ룬¾Í»áÔÚ¶ÑÇø¿ª±ÙÄڴ棬½«Æä´æ´¢ÔÚ¶ÑÇø£¬valueBuffer´æ´¢ÄÚ´æÖ¸Õë¡£
value witness tableµÄÒýÓÃ
ÒòΪProtocol TypeµÄÀàÐͲ»Í¬£¬ÄÚ´æ¿Õ¼ä£¬³õʼ»¯·½·¨µÈ¶¼²»Ïàͬ£¬ÎªÁ˶ÔProtocol TypeÉúÃüÖÜÆÚ½øÐÐרÏî¹ÜÀí£¬Óõ½ÁËValue
Witness Table¡£
protocol witness tableµÄÒýÓÃ
¹ÜÀíProtocol TypeµÄ·½·¨·ÖÅÉ¡£
ÄÚ´æ·Ö²¼ÈçÏ£º
1. payload_data_0
= 0x0000000000000004,
2. payload_data_1 = 0x0000000000000000,
3. payload_data_2 = 0x0000000000000000,
4. instance_type = 0x000000010d6dc408 ExistentialContainers`type
metadata for ExistentialContainers.Car,
5. protocol_witness_0 = 0x000000010d6dc1c0
ExistentialContainers protocol witness table for
ExistentialContainers.Car:ExistentialContainers.Drivable
in ExistentialContainers |
Protocol Witness Table£¨PWT£©
ΪÁËʵÏÖClass¶à̬Ҳ¾ÍÊÇÒýÓÃÓïÒå¶à̬£¬ÐèÒªV-TableÀ´ÊµÏÖ£¬µ«ÊÇV-TableµÄǰÌáÊǾßÓÐͬһ¸ö¸¸À༴¹²ÏíÏàͬµÄ¼Ì³Ð¹ØÏµ£¬µ«ÊǶÔÓÚProtocol
TypeÀ´Ëµ£¬²¢²»¾ß±¸´ËÌØÕ÷£¬¹ÊΪÁËÖ§³ÖStructµÄ¶à̬£¬ÐèÒªÓõ½protocol oriented
programming»úÖÆ£¬Ò²¾ÍÊǽèÖúProtocol Witness TableÀ´ÊµÏÖ£¨Ï¸½Ú¿ÉÒÔµã»÷VtableºÍwitness
tableʵÏÖ£¬Ã¿¸ö½á¹¹Ìå»á´´ÔìPWT±í£¬ÄÚ²¿°üº¬Ö¸Õ룬ָÏò·½·¨¾ßÌåʵÏÖ£©¡£

Value Witness Table£¨VWT£©
ÓÃÓÚ¹ÜÀíÈÎÒâÖµµÄ³õʼ»¯¡¢¿½±´¡¢Ïú»Ù¡£

VWT use existential container
Value Witness TableµÄ½á¹¹ÈçÉÏ£¬ÊÇÓÃÓÚ¹ÜÀí×ñÊØÁËÐÒéµÄProtocol TypeʵÀýµÄ³õʼ»¯£¬¿½±´£¬ÄÚ´æÏû¼õºÍÏú»ÙµÄ¡£
Value Witness TableÔÚSILÖл¹¿ÉÒÔ²ð·ÖΪ%relative_vwtableºÍ%absolute_vwtable£¬ÎÒÃÇÕâÀïÏȲ»×öÕ¹¿ª¡£
Value Witness TableºÍProtocol Witness Tableͨ¹ý·Ö¹¤£¬È¥¹ÜÀíProtocol
TypeʵÀýµÄÄÚ´æ¹ÜÀí£¨³õʼ»¯£¬¿½±´£¬Ïú»Ù£©ºÍ·½·¨µ÷Óá£
ÎÒÃÇÀ´½èÖú¾ßÌåµÄʾÀý½øÐнøÒ»²½Á˽⣺
// Protocol Types
// The Existential Container in action
func drawACopy(local £ºDrawable) {
local.draw()
}
let val :Drawable = Point()
drawACopy(val) |
ÔÚSwift±àÒëÆ÷ÖУ¬Í¨¹ýExistential ContainerʵÏÖµÄα´úÂëÈçÏ£º
// Protocol
Types
// The Existential Container in action
func drawACopy(local :Drawable) {
local.draw()
}
let val :Drawable = Point()
drawACopy(val)
//existential containerµÄα´úÂë½á¹¹
struct ExistContDrawable {
var valueBuffer:(Int, Int, Int)
var vwt:ValueWitnessTable
var pwt:DrawableProtocolWitnessTable
}
// drawACopy·½·¨Éú³ÉµÄα´úÂë
func drawACopy(val:ExistContDrawable) { //½«existential
container´«Èë
var local = ExistContDrawable() //³õʼ»¯container
let vwt = val.vwt //»ñÈ¡value witness table£¬ÓÃÓÚ¹ÜÀíÉúÃüÖÜÆÚ
let pwt = val.pwt //»ñÈ¡protocol witness table£¬ÓÃÓÚ½øÐз½·¨·ÖÅÉ
local.type = type
local.pwt = pwt
vwt.allocateBufferAndCopyValue(&local, val)
//vwt½øÐÐÉúÃüÖÜÆÚ¹ÜÀí£¬³õʼ»¯»òÕß¿½±´
pwt.draw(vwt.projectBuffer(&local)) //pwt²éÕÒ·½·¨£¬ÕâÀï˵һÏÂprojectBuffer£¬ÒòΪ²»Í¬ÀàÐÍÔÚÄÚ´æÖÐÊDz»Í¬µÄ£¨small
valueÄÚÁªÔÚÕ»ÄÚ£¬large value³õʼ»¯ÔÚ¶ÑÄÚ£¬Õ»³ÖÓÐÖ¸Õ룩£¬ËùÒÔ·½·¨µÄÈ·¶¨Ò²ÊǺÍÀàÐÍÏà¹ØµÄ£¬ÎÒÃÇÖªµÀ£¬²éÕÒ·½·¨Ê±ÊÇͨ¹ýµ±Ç°¶ÔÏóµÄµØÖ·£¬Í¨¹ýÒ»¶¨µÄÎ»ÒÆÈ¥²éÕÒ·½·¨µØÖ·¡£
vwt.destructAndDeallocateBuffer(temp) //vwt½øÐÐÉúÃüÖÜÆÚ¹ÜÀí£¬Ïú»ÙÄÚ´æ
} |
Protocol Type ´æ´¢ÊôÐÔ
ÎÒÃÇÖªµÀ£¬SwiftÖÐClassµÄʵÀýºÍÊôÐÔ¶¼´æ´¢ÔÚ¶ÑÇø£¬StructʵÀýÔÚÕ»Çø£¬Èç¹û°üº¬Ö¸ÕëÊôÐÔÔò´æ´¢ÔÚ¶ÑÇø£¬Protocol
TypeÈçºÎ´æ´¢ÊôÐÔ£¿Small Numberͨ¹ýExistential ContainerÄÚÁªÊµÏÖ£¬´óÊý´æÔÚ¶ÑÇø¡£ÈçºÎ´¦ÀíCopyÄØ£¿
Protocol´óÊýµÄCopyÓÅ»¯
ÔÚ³öÏÖCopyÇé¿öʱ£º
let aLine = Line(1.0,
1.0, 1.0, 3.0)
let pair = Pair(aLine, aLine)
let copy = pair |

»á½«ÐµÄExsitential ContainerµÄvalueBufferÖ¸Ïòͬһ¸övalue¼´´´½¨Ö¸ÕëÒýÓ㬵«ÊÇÈç¹ûÒª¸Ä±äÖµÔõô°ì?ÎÒÃÇÖªµÀStructÖµµÄÐ޸ĺÍClass²»Í¬£¬CopyÊDz»Ó¦¸ÃÓ°ÏìÔʵÀýµÄÖµµÄ¡£
ÕâÀïÓõ½ÁËÒ»¸ö¼¼Êõ½Ð×öIndirect Storage With Copy-On-Write£¬¼´ÓÅÏÈʹÓÃÄÚ´æÖ¸Õ롣ͨ¹ýÌá¸ßÄÚ´æÖ¸ÕëµÄʹÓã¬À´½µµÍ¶ÑÇøÄÚ´æµÄ³õʼ»¯¡£½µµÍÄÚ´æÏûºÄ¡£ÔÚÐèÒªÐÞ¸ÄÖµµÄʱºò£¬»áÏȼì²âÒýÓüÆÊý¼ì²â£¬Èç¹ûÓдóÓÚ1µÄÒýÓüÆÊý£¬Ôò¿ª±ÙÐÂÄڴ棬´´½¨ÐµÄʵÀý¡£ÔÚ¶ÔÄÚÈݽøÐбä¸üµÄʱºò£¬»á¿ªÆôÒ»¿éеÄÄڴ棬α´úÂëÈçÏ£º
class LineStorage
{ var x1, y1, x2, y2:Double }
struct Line :Drawable {
var storage :LineStorage
init() { storage = LineStorage(Point(), Point())
}
func draw() { ¡ }
mutating func move() {
if !isUniquelyReferencedNonObjc(&storage)
{ //ÈçºÎ´æÔÚ¶à·ÝÒýÓã¬Ôò¿ªÆôÐÂÄڴ棬·ñÔòÖ±½ÓÐÞ¸Ä
storage = LineStorage(storage)
}
storage¡£start = ...
}
} |
ÕâÑùʵÏÖµÄÄ¿µÄ£ºÍ¨¹ý¶à·ÝÖ¸ÕëÈ¥ÒýÓÃͬһ·ÝµØÖ·µÄ³É±¾Ô¶Ô¶µÍÓÚ¿ª±Ù¶à·Ý¶ÑÄÚ´æ¡£ÒÔ϶ԱÈͼ£º


¶Ñ¿½±´
indirect storage
Protocol Type¶à̬×ܽá
Ö§³ÖProtocol TypeµÄ¶¯Ì¬¶à̬£¨Dynamic Polymorphism£©ÐÐΪ¡£
ͨ¹ýʹÓÃWitness TableºÍExistential ContainerÀ´ÊµÏÖ¡£
¶ÔÓÚ´óÊýµÄ¿½±´¿ÉÒÔͨ¹ýIndirect Storage¼ä½Ó´æ´¢À´½øÐÐÓÅ»¯¡£
˵µ½¶¯Ì¬¶à̬Dynamic Polymorphism£¬ÎÒÃǾÍÒªÎÊÁË£¬Ê²Ã´ÊǾ²Ì¬¶à̬Static Polymorphism£¬¿´¿´ÏÂÃæÊ¾Àý£º
// Drawing a copy
protocol Drawable {
func draw()
}
func drawACopy(local :Drawable) {
local.draw()
}
let line = Line()
drawACopy(line)
// ...
let point = Point()
drawACopy(point) |
ÕâÖÖÇé¿öÎÒÃǾͿÉÒÔÓõ½·ºÐÍGeneric codeÀ´ÊµÏÖ£¬½øÐнøÒ»²½ÓÅ»¯¡£
·ºÐÍ
ÎÒÃǽÓÏÂÀ´»áÌÖÂÛ·ºÐÍÊôÐԵĴ洢·½Ê½ºÍ·ºÐÍ·½·¨ÊÇÈçºÎ·ÖÅɵġ£·ºÐͺÍProtocol TypeµÄÇø±ðÔÚÓÚ£º
·ºÐÍÖ§³ÖµÄÊǾ²Ì¬¶à̬¡£
ÿ¸öµ÷ÓÃÉÏÏÂÎÄÖ»ÓÐÒ»ÖÖÀàÐÍ¡£
²é¿´ÏÂÃæµÄʾÀý£¬fooºÍbar·½·¨ÊÇͬһÖÖÀàÐÍ¡£
ÔÚµ÷ÓÃÁ´Öлáͨ¹ýÀàÐͽµ¼¶½øÐÐÀàÐÍÈ¡´ú¡£
¶ÔÓÚÒÔÏÂʾÀý£º
func foo<T:Drawable>(local
:T) {
bar(local)
}
func bar<T:Drawable>(local:T) { ¡ }
let point = Point()
foo(point) |
·ÖÎö·½·¨fooºÍbarµÄµ÷Óùý³Ì£º
//µ÷Óùý³Ì
foo(point)-->foo<T = Point>(point) //ÔÚ·½·¨Ö´ÐÐʱ£¬Swift½«·ºÐÍT°ó¶¨Îªµ÷Ó÷½Ê¹ÓõľßÌåÀàÐÍ£¬ÕâÀïΪPoint
bar(local) -->bar<T = Point>(local) //ÔÚµ÷ÓÃÄÚ²¿bar·½·¨Ê±£¬»áʹÓÃfooÒѾ°ó¶¨µÄ±äÁ¿ÀàÐÍPoint£¬¿ÉÒÔ¿´µ½£¬·ºÐÍTÔÚÕâÀïÒѾ±»½µ¼¶£¬Í¨¹ýÀàÐÍPoint½øÐÐÈ¡´ú |
·ºÐÍ·½·¨µ÷ÓõľßÌåʵÏÖΪ£º
ͬһÖÖÀàÐ͵ÄÈκÎʵÀý£¬¶¼¹²ÏíͬÑùµÄʵÏÖ£¬¼´Ê¹ÓÃͬһ¸öProtocol Witness Table¡£
ʹÓÃProtocol/Value Witness Table¡£
ÿ¸öµ÷ÓÃÉÏÏÂÎÄÖ»ÓÐÒ»ÖÖÀàÐÍ£ºÕâÀïûÓÐʹÓÃExistential Container£¬ ¶øÊǽ«Protocol/Value
Witness Table×÷Ϊµ÷Ó÷½µÄ¶îÍâ²ÎÊý½øÐд«µÝ¡£
±äÁ¿³õʼ»¯ºÍ·½·¨µ÷Ó㬶¼Ê¹Óô«ÈëµÄVWTºÍPWTÀ´Ö´ÐС£
¿´µ½ÕâÀÎÒÃDz¢²»¾õµÃ·ºÐͱÈProtocol TypeÓÐʲô¸ü¿ìµÄÌØÐÔ£¬·ºÐÍÈçºÎ¸ü¿ìÄØ?¾²Ì¬¶à̬ǰÌáÏ¿ÉÒÔ½øÐнøÒ»²½µÄÓÅ»¯£¬³ÆÎªÌض¨·ºÐÍÓÅ»¯¡£
·ºÐÍÌØ»¯
¾²Ì¬¶à̬£ºÔÚµ÷ÓÃÕ¾ÖÐÖ»ÓÐÒ»ÖÖÀàÐÍ
SwiftʹÓÃÖ»ÓÐÒ»ÖÖÀàÐ͵ÄÌØµã£¬À´½øÐÐÀàÐͽµ¼¶È¡´ú¡£
ÀàÐͽµ¼¶ºó£¬²úÉúÌØ¶¨ÀàÐ͵ķ½·¨
Ϊ·ºÐ͵Äÿ¸öÀàÐÍ´´Ôì¶ÔÓ¦µÄ·½·¨
ÕâʱºòÄã¿ÉÄÜ»áÎÊ£¬ÄÇÿһÖÖÀàÐͶ¼²úÉúÒ»¸öÐµķ½·¨£¬´úÂë¿Õ¼äÆñ²»±¬Õ¨?
¾²Ì¬¶à̬ϽøÐÐÌØ¶¨ÓÅ»¯specialization
ÒòΪÊǾ²Ì¬¶à̬¡£ËùÒÔ¿ÉÒÔ½øÐкÜÇ¿´óµÄÓÅ»¯£¬±ÈÈç½øÐÐÄÚÁªÊµÏÖ£¬²¢ÇÒͨ¹ý»ñÈ¡ÉÏÏÂÎÄÀ´½øÐиü½øÒ»²½µÄÓÅ»¯¡£´Ó¶ø½µµÍ·½·¨ÊýÁ¿¡£ÓÅ»¯ºó¿ÉÒÔ¸ü¾«È·ºÍ¾ßÌå¡£
ÀýÈ磺
func min<T:Comparable>(x:T,
y:T) -> T {
return y < x ? y : x
} |
´ÓÆÕͨµÄ·ºÐÍÕ¹¿ªÈçÏ£¬ÒòΪҪ֧³ÖËùÓÐÀàÐ͵Ämin·½·¨£¬ËùÒÔÐèÒª¶Ô·ºÐÍÀàÐͽøÐмÆË㣬°üÀ¨³õʼ»¯µØÖ·¡¢ÄÚ´æ·ÖÅä¡¢ÉúÃüÖÜÆÚ¹ÜÀíµÈ¡£³ýÁ˶ÔvalueµÄ²Ù×÷£¬»¹Òª¶Ô·½·¨½øÐвÙ×÷¡£ÕâÊÇÒ»¸ö·Ç³£¸´ÔÓÅÓ´óµÄ¹¤³Ì¡£
func min<T:Comparable>(x:T,
y:T, FTable:FunctionTable) -> T {
let xCopy = FTable.copy(x)
let yCopy = FTable.copy(y)
let m = FTable.lessThan(yCopy£¬ xCopy) ? y :x
FTable.release(x)
FTable.release(y)
return m
} |
ÔÚÈ·¶¨Èë²ÎÀàÐÍʱ£¬±ÈÈçInt£¬±àÒëÆ÷¿ÉÒÔͨ¹ý·ºÐÍÌØ»¯£¬½øÐÐÀàÐÍÈ¡´ú£¨Type
Substitute£©£¬ÓÅ»¯Îª£º
func min<Int>(x:Int,
y:Int) -> Int {
return y < x ? y :x
} |
·ºÐÍÌØ»¯specilizationÊǺÎʱ·¢ÉúµÄ?
ÔÚʹÓÃÌØ¶¨ÓÅ»¯Ê±£¬µ÷Ó÷½ÐèÒª½øÐÐÀàÐÍÍÆ¶Ï£¬ÕâÀïÐèÒªÖªÏþÀàÐ͵ÄÉÏÏÂÎÄ£¬ÀýÈçÀàÐ͵͍ÒåºÍÄÚ²¿·½·¨ÊµÏÖ¡£Èç¹ûµ÷Ó÷½ºÍÀàÐÍÊǵ¥¶À±àÒëµÄ£¬¾ÍÎÞ·¨ÔÚµ÷Ó÷½ÍƶÏÀàÐ͵ÄÄÚ²¿ÊµÐУ¬¾ÍÎÞ·¨Ê¹ÓÃÌØ¶¨ÓÅ»¯£¬±£Ö¤ÕâЩ´úÂëÒ»Æð½øÐбàÒ룬ÕâÀï¾ÍÓõ½ÁËwhole
module optimization¡£¶øwhole module optimizationÊǶÔÓÚµ÷Ó÷½ºÍ±»µ÷Ó÷½µÄ·½·¨ÔÚ²»Í¬Îļþʱ£¬¶ÔÆä½øÐзºÐÍÌØ»¯ÓÅ»¯µÄǰÌá¡£
·ºÐͽøÒ»²½ÓÅ»¯
ÌØ¶¨·ºÐ͵ĽøÒ»²½ÓÅ»¯£º
// Pairs in
our program using generic types
struct Pair<T :Drawable> {
init(_ f:T£¬ _ s:T) {
first = f ; second = s
}
var first:T
var second:T
}
let pairOfLines = Pair(Line(), Line())
// ...
let pairOfPoint = Pair(Point(), Point()) |
ÔÚÓõ½¶àÖÖ·ºÐÍ£¬ÇÒÈ·¶¨·ºÐÍÀàÐͲ»»áÔÚÔËÐÐʱÐÞ¸Äʱ£¬¾Í¿ÉÒԶԳɶԷºÐ͵ÄʹÓýøÐнøÒ»²½ÓÅ»¯¡£
ÓÅ»¯µÄ·½Ê½Êǽ«·ºÐ͵ÄÄÚ´æ·ÖÅäÓÉÖ¸ÕëÖ¸¶¨£¬±äΪÄÚ´æÄÚÁª£¬²»ÔÙÓжîÍâµÄ¶Ñ³õʼ»¯ÏûºÄ¡£Çë×¢Ò⣬ÒòΪ½øÐÐÁË´æ´¢ÄÚÁª£¬ÒѾȷ¶¨ÁË·ºÐÍÌØ¶¨ÀàÐ͵ÄÄÚ´æ·Ö²¼£¬·ºÐ͵ÄÄÚ´æÄÚÁª²»ÄÜ´æ´¢²»Í¬ÀàÐÍ¡£ËùÒÔÔÙ´ÎÇ¿µ÷´ËÖÖÓÅ»¯Ö»ÊÊÓÃÓÚÔÚÔËÐÐʱ²»»áÐ޸ķºÐÍÀàÐÍ£¬¼´²»ÄÜͬʱ֧³ÖÒ»¸ö·½·¨Öаüº¬lineºÍpointÁ½ÖÖÀàÐÍ¡£
###whole module optimization
whole module optimizationÊÇÓÃÓÚSwift±àÒëÆ÷µÄÓÅ»¯»úÖÆ¡£¿ÉÒÔͨ¹ý-whole-module-optimization
£¨»ò -wmo£©½øÐдò¿ª¡£ÔÚXCode 8Ö®ºóĬÈÏ´ò¿ª¡£ Swift Package ManagerÔÚreleaseģʽĬÈÏʹÓÃwhole
module optimization¡£moduleÊǶà¸öÎļþ¼¯ºÏ¡£

±àÒëÆ÷ÔÚ¶ÔÔ´Îļþ½øÐÐÓï·¨·ÖÎöÖ®ºó£¬»á¶ÔÆä½øÐÐÓÅ»¯£¬Éú³É»úÆ÷Âë²¢Êä³öÄ¿±êÎļþ£¬Ö®ºóÁ´½ÓÆ÷ÁªºÏËùÓеÄÄ¿±êÎļþÉú³É¹²Ïí¿â»ò¿ÉÖ´ÐÐÎļþ¡£
whole module optimizationͨ¹ý¿çº¯ÊýÓÅ»¯£¬¿ÉÒÔ½øÐÐÄÚÁªµÈÓÅ»¯²Ù×÷£¬¶ÔÓÚ·ºÐÍ£¬¿ÉÒÔͨ¹ý»ñÈ¡ÀàÐ͵ľßÌåʵÏÖÀ´½øÐÐÍÆ¶ÏÓÅ»¯£¬½øÐÐÀàÐͽµ¼¶·½·¨ÄÚÁª£¬É¾³ý¶àÓà·½·¨µÈ²Ù×÷¡£

ȫģ¿éÓÅ»¯µÄÓÅÊÆ
±àÒëÆ÷ÕÆÎÕËùÓз½·¨µÄʵÏÖ£¬¿ÉÒÔ½øÐÐÄÚÁªºÍ·ºÐÍÌØ»¯µÈÓÅ»¯£¬Í¨¹ý¼ÆËãËùÓз½·¨µÄÒýÓã¬ÒƳý¶àÓàµÄÒýÓüÆÊý²Ù×÷¡£
ͨ¹ýÖªÏþËùÓеķǹ«¹²·½·¨£¬Èç¹ûÕâд·½·¨Ã»Óб»Ê¹Ó㬾ͿÉÒÔ¶ÔÆä½øÐÐÏû³ý¡£
ÈçºÎ½µµÍ±àÒëʱ¼ä
ºÍȫģ¿éÓÅ»¯Ïà·´µÄÊÇÎļþÓÅ»¯£¬¼´¶Ôµ¥¸öÎļþ½øÐбàÒë¡£ÕâÑùµÄºÃ´¦ÔÚÓÚ¿ÉÒÔ²¢ÐÐÖ´ÐУ¬²¢ÇÒ¶ÔÓÚûÓÐÐ޸ĵÄÎļþ²»»áÔٴαàÒ롣ȱµãÔÚÓÚ±àÒëÆ÷ÎÞ·¨»ñ֪ȫò£¬ÎÞ·¨½øÐÐÉî¶ÈÓÅ»¯¡£ÏÂÃæÎÒÃÇ·ÖÎöÏÂȫģ¿éÓÅ»¯ÈçºÎ±ÜÃâûÐ޸ĵÄÎļþÔٴαàÒë¡£

±àÒëÆ÷ÄÚ²¿ÔËÐйý³Ì·ÖΪ£ºÓï·¨·ÖÎö£¬ÀàÐͼì²é£¬SILÓÅ»¯£¬LLVMºó¶Ë´¦Àí¡£
Óï·¨·ÖÎöºÍÀàÐͼì²éÒ»°ãºÜ¿ì£¬SILÓÅ»¯Ö´ÐÐÁËÖØÒªµÄSwiftÌØ¶¨ÓÅ»¯£¬ÀýÈç·ºÐÍÌØ»¯ºÍ·½·¨ÄÚÁªµÈ£¬¸Ã¹ý³Ì´ó¸ÅÕ¼ÓÃÕû¸ö±àÒëʱ¼äµÄÈý·ÖÖ®Ò»¡£LLVMºó¶ËÖ´ÐÐÕ¼ÓÃÁ˴󲿷ֵıàÒëʱ¼ä£¬ÓÃÓÚÔËÐнµ¼¶ÓÅ»¯ºÍÉú³É´úÂë¡£
½øÐÐȫģ¿éÓÅ»¯ºó£¬SILÓÅ»¯»á½«Ä£¿éÔٴβð·ÖΪ¶à¸ö²¿·Ö£¬LLVMºó¶Ëͨ¹ý¶àÏ̶߳ÔÕâЩ²ð·ÖÄ£¿é½øÐд¦Àí£¬¶ÔÓÚûÓÐÐ޸ĵIJ¿·Ö£¬²»»á½øÐÐÔÙ´¦Àí¡£ÕâÑù¾Í±ÜÃâÁËÐÞ¸ÄһС²¿·Ö£¬Õû¸ö´óÄ£¿é½øÐÐLLVMºó¶ËµÄÔÙ´ÎÖ´ÐУ¬³ý´ËÍ⣬ʹÓöàÏ̲߳¢ÐвÙ×÷Ò²»áËõ¶Ì´¦Àíʱ¼ä¡£
À©Õ¹£ºSwiftµÄÒþ²Ø¡°Bug¡±
SwiftÒòΪ·½·¨·ÖÅÉ»úÖÆÎÊÌ⣬ËùÒÔÔÚÉè¼ÆºÍÓÅ»¯ºó£¬»á²úÉúºÍÎÒÃdz£¹æÀí½â²»Ì«Ò»ÖµĽá¹û£¬Õ⵱Ȼ²»ÄÜËãBug¡£µ«ÊÇ»¹ÊÇÒªµ¥¶À½øÐÐ˵Ã÷£¬±ÜÃâÔÚ¿ª·¢¹ý³ÌÖУ¬ÒòΪ¶Ô»úÖÆµÄÕÆÎÕ²»×㣬Ôì³ÉÔ¤ÆÚºÍÖ´ÐгöÈëµ¼ÖµÄÎÊÌâ¡£
Message dispatch
ÎÒÃÇͨ¹ýÉÏÃæËµÃ÷½áºÏStatic dispatch VS Dynamic dispatch¶Ô·½·¨·ÖÅÉ·½Ê½ÓÐÁËÁ˽⡣ÕâÀïÐèÒª¶ÔObjective-CµÄ·½·¨·ÖÅÉ·½Ê½½øÐÐ˵Ã÷¡£
ÊìϤOCµÄÈ˶¼ÖªµÀ£¬OC²ÉÓÃÁËÔËÐÐʱ»úÖÆÊ¹ÓÃobj_msgSend·¢ËÍÏûÏ¢£¬runtime·Ç³£µÄÁé»î£¬ÎÒÃDz»½ö¿ÉÒÔ¶Ô·½·¨µ÷ÓòÉÓÃswizzling£¬¶ÔÓÚ¶ÔÏóÒ²¿ÉÒÔͨ¹ýisa-swizzlingÀ´À©Õ¹¹¦ÄÜ£¬Ó¦Óó¡¾°ÓÐÎÒÃdz£ÓõÄhookºÍ´ó¼ÒÊìÖªµÄKVO¡£
´ó¼ÒÔÚʹÓÃSwift½øÐпª·¢Ê±¶¼»áÎÊ£¬SwiftÊÇ·ñ¿ÉÒÔʹÓÃOCµÄÔËÐÐʱºÍÏûϢת·¢»úÖÆÄØ£¿´ð°¸ÊÇ¿ÉÒÔ¡£
Swift¿ÉÒÔͨ¹ý¹Ø¼ü×Ödynamic¶Ô·½·¨½øÐбê¼Ç£¬ÕâÑù¾Í»á¸æËß±àÒëÆ÷£¬´Ë·½·¨Ê¹ÓõÄÊÇOCµÄÔËÐÐʱ»úÖÆ¡£
×¢Ò⣺ÎÒÃdz£¼ûµÄ¹Ø¼ü×Ö@ObjC²¢²»»á¸Ä±äSwiftÔÓеķ½·¨·ÖÅÉ»úÖÆ£¬¹Ø¼ü×Ö@ObjCµÄ×÷ÓÃÖ»ÊǸæËß±àÒëÆ÷£¬¸Ã¶Î´úÂë¶ÔÓÚOC¿É¼û¡£
×ܽáÀ´Ëµ£¬Swiftͨ¹ýdynamic¹Ø¼ü×ÖµÄÀ©Õ¹ºó£¬Ò»¹²°üº¬ÈýÖÖ·½·¨·ÖÅÉ·½Ê½£ºStatic
dispatch£¬Table dispatchºÍMessage dispatch¡£
Swift dispatch method
Èç¹ûÔÚ¿ª·¢¹ý³ÌÖУ¬´íÎóµÄ»ìºÏÁËÕ⼸ÖÖ·ÖÅÉ·½Ê½£¬¾Í¿ÉÄܳöÏÖBug£¬ÒÔÏÂÎÒÃǶÔÕâЩBug½øÐзÖÎö£º
SR-584
´ËÇé¿öÊÇÔÚ×ÓÀàµÄextensionÖÐÖØÔØ¸¸Àà·½·¨Ê±£¬³öÏÖºÍÔ¤ÆÚ²»Í¬µÄÐÐΪ¡£
class Base:NSObject
{
var directProperty:String { return "This
is Base" }
var indirectProperty:String { return directProperty
}
}
class Sub:Base { }
extension Sub {
override var directProperty:String { return
"This is Sub" }
} |
Ö´ÐÐÒÔÏ´úÂ룬ֱ½Óµ÷ÓÃûÓÐÎÊÌ⣺
Base().directProperty
// ¡°This is Base¡±
Sub().directProperty // ¡°This is Sub¡± |
¼ä½Óµ÷Óýá¹ûºÍÔ¤ÆÚ²»Í¬£º
Base£¨£©¡£indirectProperty
// ¡°This is Base¡±
Sub£¨£©¡£indirectProperty // expected "this
is Sub"£¬but is ¡°This is Base¡± <- Unexpected! |
ÔÚBase.directPropertyǰÌí¼Ódynamic¹Ø¼ü×־ͿÉÒÔ»ñµÃ"this is
Sub"µÄ½á¹û¡£SwiftÔÚextension ÎĵµÖÐ˵Ã÷£¬²»ÄÜÔÚextensionÖÐÖØÔØÒѾ´æÔڵķ½·¨¡£
¡°Extensions can add new functionality to a type,
but they cannot override existing functionality.¡±
»á³öÏÖ¾¯¸æ£ºCannot override a non-dynamic class declaration
from an extension¡£

³öÏÖÕâ¸öÎÊÌâµÄÔÒòÊÇ£¬NSObjectµÄextensionÊÇʹÓõÄMessage dispatch£¬¶øInitial
DeclarationʹÓõÄÊÇTable dispath£¨²é¿´ÉÏͼ Swift Dispatch Method£©¡£extensionÖØÔØµÄ·½·¨Ìí¼ÓÔÚÁËMessage
dispatchÄÚ£¬Ã»ÓÐÐÞ¸ÄÐ麯Êý±í£¬Ð麯Êý±íÄÚ»¹ÊǸ¸ÀàµÄ·½·¨£¬¹Ê»áÖ´Ðи¸Àà·½·¨¡£ÏëÔÚextensionÖØÔØ·½·¨£¬ÐèÒª±êÃ÷dynamicÀ´Ê¹ÓÃMessage
dispatch¡£
SR-103
ÐÒéµÄÀ©Õ¹ÄÚʵÏֵķ½·¨£¬ÎÞ·¨±»×ñÊØÀàµÄ×ÓÀàÖØÔØ£º
protocol Greetable
{
func sayHi()
}
extension Greetable {
func sayHi() {
print("Hello"£©
}
}
func greetings(greeter£ºGreetable) {
greeter.sayHi()
} |
ÏÖÔÚ¶¨ÒåÒ»¸ö×ñÊØÁËÐÒéµÄÀàPerson¡£×ñÊØÐÒéÀàµÄ×ÓÀàLoudPerson£º
class Person:Greetable
{
}
class LoudPerson:Person {
func sayHi() {
print("sub")
}
} |
Ö´ÐÐÏÂÃæ´úÂë½á¹ûΪ£º
var sub:LoudPerson
= LoudPerson()
sub.sayHi() //sub |
²»·ûºÏÔ¤ÆÚµÄ´úÂ룺
var sub:Person
= LoudPerson()
sub.sayHi() //HellO <-ʹÓÃÁËprotocolµÄĬÈÏʵÏÖ |
×¢Ò⣬ÔÚ×ÓÀàLoudPersonÖÐûÓгöÏÖoverride¹Ø¼ü×Ö¡£¿ÉÒÔÀí½âΪLoudPerson²¢Ã»Óгɹ¦×¢²áGreetableÔÚWitness
tableµÄ·½·¨¡£ËùÒÔ¶ÔÓÚÉùÃ÷ΪPersonʵ¼ÊΪLoudPersonµÄʵÀý£¬»áÔÚ±àÒëÆ÷ͨ¹ýPersonÈ¥²éÕÒ£¬PersonûÓÐʵÏÖÐÒé·½·¨£¬Ôò²»²úÉúWitness
table£¬sayHi·½·¨ÊÇÖ±½Óµ÷Óõġ£½â¾ö°ì·¨ÊÇÔÚbaseÀàÄÚʵÏÖÐÒé·½·¨£¬ÎÞÐèʵÏÖÒ²ÒªÌṩĬÈÏ·½·¨¡£»òÕß½«»ùÀà±ê¼ÇΪfinalÀ´±ÜÃâ¼Ì³Ð¡£
½øÒ»²½Í¨¹ýʾÀýÈ¥Àí½â£º
// Defined protocol¡£
protocol A {
func a() -> Int
}
extension A {
func a() -> Int {
return 0
}
}
// A class doesn't have implement of the function¡£
class B£ºA {}
class C£ºB {
func a() -> Int {
return 1
}
}
// A class has implement of the function¡£
class D£ºA {
func a() -> Int {
return 1
}
}
class E£ºD {
override func a() -> Int {
return 2
}
}
// Failure cases¡£
B().a() // 0
C().a() // 1
(C() as A).a() // 0 # We thought return 1¡£
// Success cases¡£
D().a() // 1
(D() as A).a() // 1
E().a() // 2
(E() as A).a() // 2 |
ÆäËû
ÎÒÃÇÖªµÀClass extensionʹÓõÄÊÇStatic Dispatch£º
class MyClass
{
}
extension MyClass {
func extensionMethod() {}
}
class SubClass£ºMyClass {
override func extensionMethod() {}
} |
ÒÔÉÏ´úÂë»á³öÏÖ´íÎó£¬ÌáʾDeclarations in extensions can not be
overridden yet¡£
×ܽá
Ó°Ïì³ÌÐòµÄÐÔÄܱê×¼ÓÐÈýÖÖ£º³õʼ»¯·½Ê½£¬ ÒýÓÃÖ¸ÕëºÍ·½·¨·ÖÅÉ¡£
ÎÄÖжԱÈÁËÁ½ÖÖÊý¾Ý½á¹¹£ºStructºÍClassµÄÔÚ²»Í¬±ê׼ϵÄÐÔÄܱíÏÖ¡£SwiftÏà±ÈOCºÍÆäËüÓïÑÔÇ¿»¯Á˽ṹÌåµÄÄÜÁ¦£¬ËùÒÔÔÚÁ˽âÒÔÉÏÐÔÄܱíÏÖµÄǰÌáÏ£¬Í¨¹ýÀûÓýṹÌå¿ÉÒÔÓÐЧÌáÉýÐÔÄÜ¡£
ÔÚ´Ë»ù´¡ÉÏ£¬ÎÒÃÇ»¹½éÉÜÁ˹¦ÄÜÇ¿´óµÄ½á¹¹ÌåµÄÀࣺProtocol TypeºÍGeneric¡£²¢ÇÒ½éÉÜÁËËüÃÇÈçºÎÖ§³Ö¶à̬ÒÔ¼°Í¨¹ýʹÓÃÓÐÌõ¼þÏÞÖÆµÄ·ºÐÍÈçºÎÈóÌÐò¸ü¿ì¡£ |