objective-c的動態性可以讓我們幹很多事情。比如method swizzling.
但method swizzling
有很多負面影響,特別是引入第三方元件後. 如果希望在執行時檢測,method是否被swizzling呢?
最近在翻看clang文件時發現可以使用這樣一種方法:
static inline bool isdiff(const char *func, sel _cmd)
; if (strlen(func) > 2)
return false;
}#define alert_if_method_replaced assert(!isdiff(__pretty_function__, _cmd));
__pretty_function__
是乙個編譯器的巨集,在編譯期就由編譯器決定了,以-[myobject dosth]
為例,在該方法內__pretty_function__
為"-[myobject dosth]".而_cmd
是方法的隱藏引數,是動態的,同樣以-[myobject dosth]
為例,_cmd
為"dosth",如果我們執行了一下**:
method ori_method = class_getinstancemethod([myobject class], @selector(dosth));
method replace_method = class_getinstancemethod([myobject class], @selector(dosth2));
method_exchangeimplementations(ori_method, replace_method);
那麼在原來的-[myobject dosth]
函式體中,_cmd
為"dosth2",而__pretty_function__
保持不變。
利用上述特性,前文提到的巨集就可以工作了。如下述**:
method ori_method = class_getinstancemethod([myobject class], @selector(dosth));
method replace_method = class_getinstancemethod([myobject class], @selector(dosth2));
method_exchangeimplementations(ori_method, replace_method);
- (void) dosth
- (void) dosth2
然而一般情況下此方法,並沒有什麼卵用╮(╯_╰)╭
因為但凡重要的方法,一般是系統方法,如-[uiviewcontroller viewdidload]
,因為無法在該函式體使用上述巨集,所以無法檢測是否有swizzle。此外如果在dosth2
中並沒有呼叫dosth2
,那麼也沒有效果。
這裡有一篇講如何獲取當前method的imp,戳這裡.試了一下,年代比較久遠。可用性已經不太好了。╮(╯_╰)╭
不過。在作者的實現使用了__builtin_return_address(0)
,獲取當前棧的返回位址。這是值得習得的小技能。
後面會繼續找一些優雅的檢測系統方法被method swizzling
的情形。imp相關的東西比較有意思。持續發現中。
原作寫於segmentfault 鏈結
如何判斷新網域名稱是否被K過
如何判斷新網域名稱是否被k過 大家在製作完乙個 以後,都要給這個 選個網域名稱,而網域名稱的選擇在優化中也是很重要的一步,選擇乙個好的網域名稱,對 的發展會有很大的幫助,如果選擇了乙個被k過或者作弊過的網域名稱,那麼對於 的流量特別是在搜尋引擎中的表現,那就有很大的影響了,那麼如何才能判斷乙個網域名...
判斷檔案是否被開啟
判斷檔案是否被開啟 方法一 通過try catch對檔案的移動操作,如果檔案開啟,將不能移動,會進入catch段 通過返回bool值來反應是否能正常移動 private void button2 click object sender,eventargs e private static bool ...
如何判斷乙個檔案是否被關閉?
做專案的時候遇到了下面這個問題 如何判斷乙個開啟的txt檔案是否被關閉?在開啟乙個txt檔案的時候,notepad程式是自動通過檔案路徑的引數首先複製檔案,然後馬上就關閉了檔案通道,這個時候開啟的其實只是notepad程式而不是檔案本身。檔案本身的開啟與關閉是一瞬間的事情。也就是說notepad程式...