Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ÉîÈëÆÊÎöSwiftÐÔÄÜÓÅ»¯
 
  2151  次浏览      29
 2018-11-21
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÃÀÍż¼ÊõÍŶÓ,ÏÂÃæÎÒÃǽ«´ÓÕâÁ½¸ö½Ç¶ÈÇÐÈ룬¶Ô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¡£²¢ÇÒ½éÉÜÁËËüÃÇÈçºÎÖ§³Ö¶à̬ÒÔ¼°Í¨¹ýʹÓÃÓÐÌõ¼þÏÞÖÆµÄ·ºÐÍÈçºÎÈóÌÐò¸ü¿ì¡£

   
2151 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì