昨天在翻閱DZNEmptyDataSet
源碼時發現了一些有趣的東西,如今和你們分享下:objective-c
Method-Swizzling
不是在+load
方法中Method-Swizzling
的方式並無使用method_exchangeImplementations()
函數下面一塊兒來探索一番吧!函數
這點比較好理解,直到須要的時候纔去Swizzling
,而不是在+load
方法中。關於在+load
方法中進行Method-Swizzling
,這裏有篇文章參考。下面是相關方法的截圖。具體代碼你們能夠去GitHub圍觀。 spa
這點須要細說下。平時你們對於Method-Swizzling
的印象大多停留在+load
的階段,忽然間,這個源碼裏找不到+load
的影子,感受少了點啥。還好DZNEmptyDataSet
留下了參考,讓咱們一探究竟。3d
下面的觀點來源於這裏,你們能夠自行參考code
假設如今有以下類實現: cdn
在咱們本身的實現方法swizzle_originalMethod
中,經過[self swizzle_originalMethod];
調用了原有的方法實現,這是你們一般的作法。blog
換成發送消息的寫法就是:get
((void(*)(id, SEL))objc_msgSend)(self, @selector(swizzle_originalMethod));
複製代碼
再看下沒有Method-Swizzling
以前,對原有實現的調用時什麼樣的:源碼
((void(*)(id, SEL))objc_msgSend)(self, @selector(originalMethod));
複製代碼
二者對比,很明顯,咱們改變了發送消息時的第二個參數 - 方法選擇子
,也就是說這種Method-Swizzling
技術留有「罪證」。若是原有方法實現依賴了這個方法選擇子
,它將沒法正常工做。it
method_setImplementation
直接給出代碼:
咱們使用了method_setImplementation
方法替換以前的實現,並使用靜態變量
保存了原有實現。這樣就不會以前的問題了。達到了無痕
的目的。
固然,這裏的method_setImplementation
也須要控制其執行的次數的!!!
多翻看大神們的源碼,仍是有好處的。😂😂😂