Objective-C與Swift混編實踐
前言
由于Swift的語法趨于穩定,目前本人負責的項目也已經在小范圍地引入Swift。關于混編過程中遇到的各種思考與選擇,胡波的 這篇文章 已經闡述得得比較全面了,看完文章回頭看自己在混編過程中的各種選擇,與胡先生的看法是一致的。在此梳理一下一些值得注意的小細節。
Optional
基于Objective-C的工程一般都是將JSON轉為Model,把數據以Model的形式在對象之間傳遞。當服務器傳過來的值為空或者類型錯誤時,大部分解析框架都會將相對應的值置為nil。我們知道在Objective-C的世界里,向nil發送消息是不會引發任何錯誤的。
Objective-C中沒有任何問題的屬性:
@property (nonatomic, strong) NSString *GroupName;
到了Swift的世界里,變成了:
沒錯,隱式解析的存在,導致了容錯能力的下降。只要服務端回傳的參數中有一個空字段,必然引發Crash。這簡直是自尋死路。
因此我們需要在Objective-C中,將屬性標上 nullable ,這樣Swift中該屬性變成了optional,然后采用 if let 或者 guard let 來安全地拆包。
即使業務上決定了某些字段絕對不可能為null,也仍然要將其設為nullable。校驗任何外來輸入是編程時的基本準則之一。
想必大家也想到了,這樣一來,在混編的過程中,if let充斥著Swift的代碼,雖然保證了安全,但一定程度上降低了開發效率。個人還在不斷摸索解決這個問題的方法。
Selector
在Objective-C的世界里, @selector 是我們的老朋友了。但到了Swift中我們不得不這樣來用 Selector :
self.addTarget(self, action: "resignFristResponder", forControlEvents: .EditingDidEndOnExit)
如果不仔細看,一定不會發現上面的代碼中我錯將 resignFirstResponder 寫成了 resignFristResponder 。這在編譯時不會出現任何提醒,但到了運行時會引起崩潰。
幸運的是,Swift2.2用 #selector 關鍵字替代了字符串反射。此時拼寫錯誤可以被編譯期正確地糾正了--因為編譯期會檢查到方法不存在,并報一個error。
你可以這樣寫一個不帶參數的selector:
selector(resignFirstResponder)
</pre>
如果是帶參數的selector,則會稍微特別一點:
selector(textFieldDidChange(_:)
</pre>
采用下劃線來忽略參數名,但記得保留分號。
有一點需要注意一下,Selector只支持反射Objective-C的方法,如果想要讓#selector能正確識別Swift的方法,需要在方法前面加上 @objc 關鍵字
命名
Swift得益于Module而避免了類的命名沖突。在用Swift編寫代碼的時候,應當遵循Apple官方的命名規范。例如類命名不需要在類名前加前綴。如果類也需要在Objective-C中被調用,可以用@objc關鍵字來為Objective-C生成對應的類名。
@objc(PSLimitedTextField) public class LimitedTextField: UITextField {同時API的設計也建議按照官方的 指導原則 來。我從開始寫Objective-C時就盡量模仿Apple的命名方式,后來在Objective-C到Swift的自動橋接上嘗到了甜頭。比如說:
- (instancetype)initWithName:(NSString *)name;
</pre>
被自動橋接成了
init(name: String)
工廠方法
如果仔細對比Objective-C和Swift的接口,你會發現有的類的工廠方法消失了,有的類的還在。這同樣是由于命名的問題所導致的。Apple將那些同類名一致的工廠方法橋接成了init方法,將一些默認單詞(default,standard,shared etc.)開頭的工廠方法保留了下來。
如: [NSDate date] 變成了 NSDate() .
但 [NSUserDefaults standardUserDefaults] ,保留了下來,變成了 NSUserDefaults.standardUserDefaults()
PSNumberPad 就因為工廠方法的命名問題,沒能自動橋接成Swift的方法。因此,在混編過程中,如果Objective-C的組件有可能被Swift調用的,需要妥善設計接口以便自動橋接。一個最佳實踐是,多采用 convince initialzer 替代工廠方法。
參考資料
在混編的過程中,大部分問題你可以在 這里 找到想要的答案。再一次感謝Apple完善的文檔!