Swift 3.1 實(shí)現(xiàn) Method Swizzling

在Swift3.1 之前,Method Swizzling的實(shí)現(xiàn)都放在了initialize()方法中,即

open override class func initialize() { // Method Swizzling }

我們?cè)?initialize()中實(shí)現(xiàn)Method Swizzling,是因?yàn)檫@個(gè)方法是每一個(gè)Class都必須實(shí)現(xiàn)且一定會(huì)執(zhí)行的方法,它就相當(dāng)于給我們提供了一個(gè)入口,允許我們將runtime代碼插入到適當(dāng)?shù)奈恢谩?br>

但是在3.1之后,蘋果官方已經(jīng)不建議在 Swift中 override initialize Method ,如果你嘗試override,Xcode會(huì)提示: 'initialize()' defines Objective-C class method 'initialize', which is not guaranteed to be invoked by Swift and will be disallowed in future versions

之前喵神有在他的書的第二版中提到過(guò)利用 override initialize 來(lái)做 Method Swizzling , 但在第三版更新的時(shí)候刪除了這部分內(nèi)容,因?yàn)檫魃裼X得應(yīng)該用更加 Swift 化的方法來(lái)做。

那么,如果,我們非要Method Swizzling,現(xiàn)在該怎么做呢?

國(guó)外的大牛已經(jīng)提供了一種優(yōu)雅的解決方案

解決思路:我們可以利用代理模式在程序剛啟動(dòng)時(shí)使用runtime獲取所有的Class,然后對(duì)它們遍歷,如果它是Protocol的代理就立即執(zhí)行代理方法,我們只需要在代理方法中實(shí)現(xiàn)Method Swizzling代碼。

第一步:

第二步:

第三步:

完成了上述三步之后,寫兩個(gè)ViewController,第一個(gè)Controller中override viewWillDisappear, 第二個(gè)Controller中override viewWillAppear, viewDidAppear。編譯運(yùn)行,從第一個(gè)Controller push 到第二個(gè)Controller的輸出結(jié)果為

可以看到Method Swizzling已經(jīng)成功。

后記

我個(gè)人認(rèn)為,目前在代碼中需要使用runtime大多和UIKit相關(guān),而UIKit又是由OC編寫的,事實(shí)上使用OC來(lái)swizzle是最好的方法,強(qiáng)行使用Swift豈不是緣木求魚?既然蘋果都說(shuō)了 swizzle 只能用于 OC ,那就把這部分東西寫在 OC 文件里面,然后 Bridge 引用,避免以后 因Swift 語(yǔ)法變化而造成不便。

.p.s 細(xì)心的讀者可能發(fā)現(xiàn)了我在代理中定義方法用的是static,而在類中實(shí)現(xiàn)的時(shí)候替換成了class,為什么這么做呢?

因?yàn)閟taitc是無(wú)法被override的,如果你在UINavigationController中需要實(shí)現(xiàn)awake(),而你之前已經(jīng)在UIViewController中實(shí)現(xiàn)了awake(),此時(shí)你實(shí)現(xiàn)awake()就會(huì)被要求override(因?yàn)閁INavigationController繼承自UIViewController),而static方法是無(wú)法override的。喵神曾在他的書中對(duì)class和static進(jìn)行比較:在類中class和static的作用是一樣的。所以,在UIViewController中我用class替換了static。

參考鏈接

Swift 3.1 deprecates initialize(). How can I achieve the same thing?

Effective Method Swizzling in Swift

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,775評(píng)論 0 9
  • Swift2.0 1.defer譯為延緩、推遲之意類似棧 注意作用域,其次是調(diào)用順序——即一個(gè)作用域結(jié)束(注意),...
    zeqinjie閱讀 3,410評(píng)論 0 50
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,948評(píng)論 18 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,245評(píng)論 4 61
  • 2014年2月4日正式移民登陸到加拿大這塊熟悉又陌生的土地,不知不覺已經(jīng)整整三年了。閑來(lái)無(wú)事總結(jié)了一下這三年的心得...
    滄海一聲笑溫哥華閱讀 621評(píng)論 12 3