Objective-C引入了零運行時成本直接法
自S wift于2014年推出以來,Objective-C只知道一些小的變化,主要是為了驗證其與Swift的互操作性。然而,Objective-C并不是一種邊緣語言,它最近增加了對“直接”方法的支持,這些方法看起來像普通的類方法,但表現得更像C函數。
雖然Swift作為構建iOS應用程序的首選語言吸引了最大的興趣,但Objective-C仍然在開發人員中很受歡迎。事實上,如果線年首次超過TIOBE指數中的Objective-C,那么截至2019年11月,Objective-C在TIOBE指數中已經攀升至第12位,斯威夫特排名第10位。有趣的是,這兩種語言已經多次交換了他們的TIOBE排名。同樣,Stack Overflow語言排名根據流行的問答論壇上提出的問題數量來衡量語言的采用程度,這突出了人們對Objective-C的興趣下降。Stack Overflow數字可以通過Swift收集進入iOS開發領域的大多數新開發人員,以及過去幾年對Objective-C的修改次數減少來具體解釋。
盡管如此,Objective-C的新功能還是讓很多人感到有些意外。簡而言之,一個直接方法允許定義一些特殊類型的屬性,這些屬性不附帶Objective-C元數據,其getter和setter方法幾乎表現為直C函數。這個新特性的語法是Objective-C@property語法的直接擴展:
直接方法的使用通過objc_msgSend消除了與Objective-C運行時方法解析相關的一些開銷..這使得使用這個新功能來優化一些關鍵路徑變得有趣,就像PSPD FKit知名度的iOS開發人員彼得·斯坦伯格在Twitter上所說的那樣。無論如何,并不是所有的開銷都被刪除,因為LLVM中的直接方法實現力求使其與標準的Object-C方法兼容。特別是,隱式self和_cmd參數都被保留,并進行了一些檢查,以確保兩者在調用方法時都是正常的。
開發人員如何使用直接方法有一些限制。首先,直接方法只能在內部、私有API上使用,不能被框架公開。此外,重載的方法不能是直接的,也不能是直接的方法,也不能重載直接的方法;實現不能重新聲明它與直接的接口的非直接方法;所需的協議方法不能是直接的;最后,您不能發送不限定的id直接方法。
除了優化關鍵路徑的可能性外,對這一新的客觀-C特征的反應并不完全是積極的一面。iOS開發人員TannerB評論說,直接方法損害了許多基本的目標C特性,如KVC、KVO、方法閃爍等。第一天應用程序開發商BJ Homer表示,他擔心蘋果可能會使用直接方法來使調整更難完成:
objc_direct_member注釋似乎有效地實現了Objc的真正私有方法。靜態發送,不可覆蓋。我可以看到蘋果在內部大量使用這種方法來避免人們調用私有方法。
這一擔憂在某種程度上被著名的iOS開發者和圖書作者尼克·洛克伍德所忽視,因為直接方法只能是私人的:
這應該有助于減輕人們的擔憂,即它將從根本上改變Objective-C的性質,方法是阻止像KVO這樣的滑動和破壞功能。
蘋果高級軟件工程師皮埃爾·哈布齊特也證實了這一點。
最后,雖然直接方法已經合并為LLVM,但不太可能在明年WWDC之前在X code中提供這些方法。