這篇文章不是介紹什麼是方法交換,這類文章很多,如果你不知道什麼是方法交換可以看這篇文章: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的效果麼,坑我半個多小時。為加驗證,是手動呼叫...