改用swift來思考

改用swift來思考

現(xiàn)有代碼庫 + 你的頭腦 + Swift。 怎么會錯呢?

原文鏈接: Switching Your Brain to Swift

  • 原文日期: 2015/08/17
  • 譯文日期: 2015/09/04
  • 譯者:ray16897188

本文原基于360iDev 2015的一次談話朋贬。等有視頻之后我會貼上連接碧磅。與此同時例获,何不看看我在elsewhere上其他的Swift文章杈抢,以及我Twitter的主頁呢?

完美的情形當然是從零開始的一個100% Swift的項目庆捺。如果你能這么做古今,很棒!但對與我們中的那些手里已經(jīng)有現(xiàn)成代碼庫滔以,而且有點兒想試試Swift的人來說捉腥,我們能從哪里開始?

為什么你画?

退一步:你為什么想用Swift去寫代碼呢抵碟?很多原因:Swift是新星;Swift有更好的語法(開始口水戰(zhàn)了)坏匪;Swift是Apple指引給我們的新方向拟逮。

將來,Swift的絕倫程度還會繼續(xù)增加剥槐,并會成為大眾首選的唱歧,有最完善的技術(shù)支持的宪摧,寫OSX和iOS代碼最簡便的一種語言粒竖。

Swift是未來之路,就這么明了几于。那怎么做才能開始用Swift的方式去思考呢蕊苗?

Swift的方式

有太多要考慮的事情了,但我們從兩個大的方面說起:安全性和值語義(value semantics)沿彭。

安全性

Objective-C里的Nil棒極了朽砰。你可以給那個東西一直發(fā)消息, 好似明天是世界末日,運行時就會一直提供回應(yīng)瞧柔。

然而Swift中的Nil卻是另一個很不同的怪物漆弄。通常來講類型系統(tǒng)(type system)會把你從試圖調(diào)用空函數(shù)或者訪問空屬性中挽救出來,阻止你這么干造锅。但你能繞過類型系統(tǒng)撼唾,而這么做和在C語言中解引用一個空指針一樣糟糕:在運行時你會被友善的捕獲,然后你的app會崩潰哥蔚。

Swift中一切都關(guān)乎類型安全倒谷。一個String是一個String,那它就是一個String糙箍。此時根本就沒nil什么事兒渤愁。多想想C++中的引用而非C中的指針,因為引用永遠也不會是nil深夯。

可選類型

有了可選類型抖格,nil就又回來了。一個可選類型的String可以確實是一個String咕晋,或者是nil他挎。你必須做檢查,每一次都要捡需。

或者不做檢查:你可以強制將這個可選類型變量拆包办桨。或者將它換成一個隱式解析可選類型(implicitly unwrapped optional)站辉,這意味著它有些復(fù)雜的劣勢呢撞,但可以當非可選類型一樣去使用 - 直到它是nil的時候,app就崩潰了饰剥。

(所有的都拆包!)
(所有的都拆包!)

Cocoa里有太多可選類型殊霞,這意味著你每用其中一個,就得去檢查里面是什么汰蓉。

這就是一個大的思維轉(zhuǎn)變绷蹲。其中的思路是:你不應(yīng)該留下任何偶然因素讓發(fā)送的消息為nil。你應(yīng)該知道顾孽,一個強類型系統(tǒng)中祝钢,某種東西要么是nil,要么就有值若厚。

如果在運行時有不確定性拦英,就做檢查。不要強制去拆包测秸。

把可選類型想成是一個盒子:這個盒子要么沒有值(nil)疤估,要么就有值灾常。但是你在強制拆包它之前總要先去檢查一下。

(你得問:可選類型的盒子里面是啥?)
(你得問:可選類型的盒子里面是啥?)

還有很多其他展示Swift安全性的例子:構(gòu)造器铃拇,更少量的未定義行為(less undefined behavior)钞瀑,內(nèi)存安全。Nil的安全性是總會出現(xiàn)的一種慷荔。

值類型

值類型在Swift中隨處可見仔戈。沒什么新東西 - Objective-C就有像NSInteger和類似CGRect的結(jié)構(gòu)體這樣的基元(primitives)。但其絕大多數(shù) - NSString拧廊,NSArray等等 - 都是類(classes)监徘,因此是引用類型。

Swift中則完全相反吧碾,如果你掃一眼頭文件的話會發(fā)現(xiàn)標準庫中有80多個結(jié)構(gòu)體凰盔,只有4個類。

String倦春,numbers和集合類型在Swift中都是值類型户敬。這意味著如果你有一個可變的Swift String(是結(jié)構(gòu)體)并把它傳給一個函數(shù),你獲得的是一個拷貝(copy)睁本。重復(fù)一遍尿庐,這并非一個嚇人的新概念:我們在Objective-C中已經(jīng)做了很久的copy和mutableCopy。這里大的轉(zhuǎn)變是對于多數(shù)常見類型來說這是新的缺省行為呢堰。

不幸的是抄瑟,如果你在Swift中用結(jié)構(gòu)體寫了些很棒的代碼,在Objective-C中你是不能回訪它們的枉疼。這就把我們帶到了下一個話題:橋接皮假。

橋接

Swift理所當然的被設(shè)計成了能與Objective-C良好協(xié)同工作。這基本上是一個必要的骂维,無需爭論的事實惹资,因為Cocoa是為Objective-C而建立。所有這些Cocoa的API必須能夠從Swift調(diào)用航闺,這意味著你自己的Objective-C的類也可以良好的橋接到Swift中褪测。

有個問題:從Swift開始,加入Objective-C代碼潦刃,然后想在Objective-C中調(diào)用你的Swift代碼侮措。

從Swift到Objective-C

有太多的Swift特性完全不能橋接到Objective-C里,比如Swift自己的結(jié)構(gòu)體和增強的枚舉類型福铅。這意味著如果你用Swift里所有最酷的特性寫出來的最新最強的framework萝毛,其中絕大多數(shù)并不能被Objective-C訪問到。

即使你給自己做限制滑黔,僅用Swift中那些可兼容Objective-C的特性去寫笆包,你也不能從Objective-C的類派生出一個用Swift寫的子類。你可以遵循table View或collection view的模式略荡,并用delegate和布局對象(layout objects)來規(guī)避這個問題庵佣,但是如果你的API是要被繼承從而派生子類的話,還是要時刻記住這一點汛兜。

Swift中任何東西在Objective-C中都默認不可見巴粪。
如果你把你的class和protocol標記了@objc,那它們就可以在Objective-C中用了粥谬。動態(tài)調(diào)節(jié)器(dynamic modifier)也暗含著@objc的標注肛根,讓被標記的東西在Objective-C中可用,但它使那些被標記了dynamic的屬性或者方法采用的是Objective-C的動態(tài)分發(fā)(dynamic dispatch)漏策。

(Swift&Objective-C)
(Swift&Objective-C)

如果你想用swizzle之類的東西派哲,你就需要用dynamic;僅僅給它標識@objc還不足以保證objc_msgSend()能被使用掺喻,因為方法是有可能被去虛擬化(devirtualized)或者被內(nèi)聯(lián)了芭届。

重復(fù)一下,這僅僅對那些可兼容的特性有效感耙。你自己寫的Swift枚舉類型中的方法并不適用褂乍。如果你枚舉類型不是由Int型所構(gòu)建,那就兼容不了即硼。

Objective-C 到 Swift: 可空性(Nullability)

從Objective-C轉(zhuǎn)到Swift有很多好消息逃片。為了促進這個轉(zhuǎn)換過程,在Objective-C中你要給你的屬性只酥,參數(shù)和返回值類型加上標注(annotation)题诵。

  • _Null_unspecified (default) – 橋接到一個Swift隱式解析可選類型(implicitly-unwrapped optional)。
  • _Nonnull – 該值不可以是nil层皱;橋接到一個常規(guī)的引用性锭。
  • _Nullable – 該值可以是nil;橋接到一個可選類型叫胖。

如果你給你的Objective-C加了標注草冈,你就會順利的將類型橋接到Swift中。即使你沒碰過Swift瓮增,你用Objective-C的時候這些標注也會在代碼補全后出現(xiàn)怎棱。如果你告訴編譯器一個方法的參數(shù)是_Nonnull的,然后傳進去一個nil绷跑,你就會得到一個合理的編譯器警告拳恋。

開始為代碼加標注是很好的做法。使用現(xiàn)有的API的時候標注會幫到你砸捏,你開始用Swift的時候也會讓你加快速度谬运。

Objective-C 到 Swift: 輕量泛型(Lightweight Generics)

輕量泛型是Swift 2的新特性隙赁。集合類型NSArray,NSDictionary(對值類型)和NSSet可以包含任何舊的NSObject類型梆暖。

這意味著大量的類型轉(zhuǎn)換(casting)伞访。Objective-C中沒有這個問題,但是記缀洳怠:Swift是關(guān)乎安全性的厚掷。正確的轉(zhuǎn)換涉及到大量的檢查。你不應(yīng)該強制的做類型轉(zhuǎn)換级解,而應(yīng)該先測試冒黑。

現(xiàn)在有了泛型,意味著你可以在Objective-C中這樣寫:

NSArray<NSString *> * _Nonnull

這是一個會包含NSString對象的NSArray勤哗。有了可空(nullability)的注釋抡爹,你能看見它還說了這個array不會為nil,你總會得到一個array俺陋。如果你了解Java或者C++就會熟悉此處的泛型語法豁延。
然后橋接到Swift就會是這樣:

[String]

一個非常清晰的Swift String數(shù)組。
小的補充說明:輕量泛型只能應(yīng)用于基本集合類:arrays腊状,dictionaries和sets诱咏。

在渾水上架橋

我會建議從零開始新建一個Swift的項目 - 100%完全的Swift。如果你有第三方的frameworks缴挖,它們是Swift寫的還是Objective-C寫的就不會有太多影響 - 你能調(diào)用其中的任何一種袋狞。
如果你有一個現(xiàn)有的代碼庫,而且你想要開始引入Swift:那就嘗試將橋接按照從Objective-C到Swift的方向進行映屋。比如view controllers和views的具體實例在Swift中就運行的很好苟鸯;它們繼承自NSObject,如果需要的話你是可以從Object-C中訪問到它們的棚点。

(金門大橋)
(金門大橋)

但是對所有其他的來說:純Swift泛型早处,由非整型,嵌套類型瘫析,結(jié)構(gòu)體構(gòu)成的枚舉類型等等 - 就需要等到你身處于一個100% Swift世界中的那一天了砌梆。別被落下,這一天會比你想象的來的更早贬循。

在那天之前咸包,接著寫能夠友善兼容Swift的Objective-C的代碼并保持對Swift最新技術(shù)的認知吧。有太多的資源會幫助你完成過渡杖虾。

資源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市温算,隨后出現(xiàn)的幾起案子怜校,更是在濱河造成了極大的恐慌间影,老刑警劉巖注竿,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異魂贬,居然都是意外死亡巩割,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門付燥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宣谈,“玉大人,你說我怎么就攤上這事键科∥懦螅” “怎么了?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵勋颖,是天一觀的道長嗦嗡。 經(jīng)常有香客問我,道長饭玲,這世上最難降的妖魔是什么侥祭? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮茄厘,結(jié)果婚禮上矮冬,老公的妹妹穿的比我還像新娘。我一直安慰自己次哈,他們只是感情好胎署,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著窑滞,像睡著了一般琼牧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上葛假,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天障陶,我揣著相機與錄音,去河邊找鬼聊训。 笑死抱究,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的带斑。 我是一名探鬼主播鼓寺,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼勋拟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了妈候?” 一聲冷哼從身側(cè)響起敢靡,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎苦银,沒想到半個月后啸胧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡幔虏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年纺念,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片想括。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡陷谱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瑟蜈,到底是詐尸還是另有隱情烟逊,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布铺根,位于F島的核電站宪躯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏夷都。R本人自食惡果不足惜眷唉,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望囤官。 院中可真熱鬧冬阳,春花似錦、人聲如沸党饮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刑顺。三九已至氯窍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蹲堂,已是汗流浹背狼讨。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留柒竞,地道東北人政供。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親布隔。 傳聞我的和親對象是個殘疾皇子离陶,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容