需求:html
有10個類, 每一個類裏頭都有n個方法(前提是方法名有規律可循,好比 setA0,setA1…) 若是挨個去init類, 而後挨個調用方法,這樣你一天就不用幹別的了ios
簡單的解決方法能夠參考這個: iPhone開發中,動態調用類和方法git
雖說performSelector有返回值,可是在ARC下會有警告,由於方法名是動態的,系統並不知道返回值是什麼樣的類型。解決方法能夠見這篇文章: "performSelector may cause a leak because its selector is unknown"警告緣由及其解決辦法github
全文轉載過來:函數
項目中使用到了從字符串建立選擇器,編譯時發現警告:"performSelector may cause a leak because its selector is unknown"(由於performSelector的選擇器未知可能會引發泄漏),爲何在ARC模式下會出現這個警告?oop
通過搜索後,在Stackoverflow上發現了一個使人滿意的答案。見http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown。spa
在ARC模式下,運行時須要知道如何處理你正在調用的方法的返回值。這個返回值能夠是任意值,如void
,int
,char
,NSString
,id
等等。ARC經過頭文件的函數定義來獲得這些信息。因此平時咱們用到的靜態選擇器就不會出現這個警告。由於在編譯期間,這些信息都已經肯定。指針
如:code
... [someController performSelector:@selector(someMethod)]; ... - (void)someMethod { //bla bla...}
而使用[someController performSelector: NSSelectorFromString(@"someMethod")];
時ARC並不知道該方法的返回值是什麼,以及該如何處理?該忽略?仍是標記爲ns_returns_retained
仍是ns_returns_autoreleased
?orm
SEL selector = NSSelectorFromString(@"someMethod");IMP imp = [_controller methodForSelector:selector];void (*func)(id, SEL) = (void *)imp;func(_controller, selector);
當有額外參數時,如
SEL selector = NSSelectorFromString(@"processRegion:ofView:");IMP imp = [_controller methodForSelector:selector];CGRect (*func)(id, SEL, CGRect, UIView *) = (void *)imp;CGRect result = func(_controller, selector, someRect, someView);
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [someController performSelector: NSSelectorFromString(@"someMethod")] #pragma clang diagnostic pop
經過使用#pragma clang diagnostic push/pop
,你能夠告訴Clang編譯器僅僅爲某一特定部分的代碼來忽視特定警告。
若是須要忽視的警告有多處,能夠定義一個宏
#define SuppressPerformSelectorLeakWarning(Stuff) \ do { \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ Stuff; \ _Pragma("clang diagnostic pop") \ } while (0)
在產生警告也就是performSelector
的地方用使用該宏,如
SuppressPerformSelectorLeakWarning( [_target performSelector:_action withObject:self] );
若是須要performSelector
返回值的話,
id result;SuppressPerformSelectorLeakWarning( result = [_target performSelector:_action withObject:self] );
[self performSelector:aSelector withObject:nil afterDelay:0.0];
若是在接受範圍內,容許在下一個runloop執行,能夠這麼作。xCode5沒問題,但據反映,xCode6的話這個不能消除警告。