Method Swizzling中的陷阱

2021-07-26 14:36:32 字數 2029 閱讀 3473

這篇文章不是介紹什麼是方法交換,這類文章很多,如果你不知道什麼是方法交換可以看這篇文章:method swizzling

方法交換是很危險的東西,會產生一些未知的錯誤,最近在使用方法交換時就遇到了這樣的問題,在我交換了乙個系統方法後,在呼叫這個方法時會在我交換的方法中迴圈無法跳出。

最終我找到了問題的關鍵,那就是這個方法可能不存在!

每次ios版本的更新都會出現一些新的api,這些api在之前的版本中就不存在,而你在交換乙個方法時如果不考慮它是否存在,那就會導致嚴重的錯誤。

比如我曾經交換過乙個方法:

- (void)openurl:(nsurl*)url options:(nsdictionary

*)options completionhandler:(void (^ __nullable)(bool success))completion

這個方法只在ios10之後有,別人在使用的時候也會先判斷這個方法是否會被響應,但是我們看下面的交換**會先新增這個方法,如果這個方法不存在,那麼本來不會響應就變成了會響應,那麼在ios10之前的系統就會進入這個方法,導致死迴圈。

class

class = [self

class];

method

method1 = class_getinstancemethod

(class, sel1);

method

method2 = class_getinstancemethod

(class, sel2);

bool didaddmethod =

class_addmethod(class,

sel1,

method_getimplementation(method2),

method_gettypeencoding(method2));

if (didaddmethod)

else

解決這個問題也很簡單就是交換前做乙個判斷:

if (![class

instancesrespondtoselector:sel1] || ![class

instancesrespondtoselector:sel2])

如果不響應這個方法,直接返回。

為了不重複寫方法交換的**,也能減少錯誤,我們可以將其封裝,將其放在nsobject的category中再合適不過了。

nsobject+dpextension.h

#import 

@inte***ce

nsobject (dpextension)

+ (void)intancemethodexchangewithoriginselector:(sel)sel1 swizzledselector:(sel)sel2;

@end

nsobject+dpextension.m

#import

"nsobject+dpextension.h"

#import

@implementation nsobject (dpextension)

+ (void)intancemethodexchangewithoriginselector:(sel)sel1 swizzledselector:(sel)sel2

method method1 = class_getinstancemethod(class, sel1);

method method2 = class_getinstancemethod(class, sel2);

bool didaddmethod =

class_addmethod(class,

sel1,

method_getimplementation(method2),

method_gettypeencoding(method2));

if (didaddmethod) else

}@end

就是這些^_^

MFC OnCtlColor 工業控制中的陷阱

最近寫乙個長時間 大約一周 執行的程式,發現總在2個多小時的時候顯示曲線部分全黑。但是程式正常執行 日誌 採集 找了很長時間的原因。最後經過google上的資料知道說gdi物件不斷增加可能導致這個問題,最後一看正式,gdi物件不斷增加,都到7000了。查詢程式發現了問題 在onctrlcolor函式...

ArrayList中remove方法的陷阱

由於arraylist集合底層儲存結構是陣列,所以arraylist中的remove刪除方法,其實就是陣列的刪除,大家或許對於陣列的刪除都不陌生,先遍歷比較判斷是否存在,存在便刪除。原始碼如下 public boolean remove object o else return false 通過上面...

jquery mobile AJAX特性的陷阱

簡單情況是 mvc 重定向,url不變 試了n種方式,跳來跳去,無解,服務端跳,寫js跳,生成跳轉中間頁跳。失敗 後來一看,明明已經跳到新頁了,樣式什麼還是原頁的,有點火大了。出去溜一圈,喝杯水,和同事東拉西扯一通。回頭一看,突然反應過來,這不是ajax的效果麼,坑我半個多小時。為加驗證,是手動呼叫...