問題描述
項(xiàng)目中使用到了從字符串創(chuàng)建選擇器,編譯時(shí)發(fā)現(xiàn)警告:"performSelector may cause a leak because its selector is unknown"(因?yàn)閜erformSelector的選擇器未知可能會(huì)引起泄漏),為什么在ARC模式下會(huì)出現(xiàn)這個(gè)警告?
經(jīng)過搜索后,在Stackoverflow上發(fā)現(xiàn)了一個(gè)令人滿意的答案廉邑。見 http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown 。
原因
在ARC模式下,運(yùn)行時(shí)需要知道如何處理你正在調(diào)用的方法的返回值滨达。這個(gè)返回值可以是任意值,如 void , int , char , NSString , id 等等俯艰。ARC通過頭文件的函數(shù)定義來得到這些信息捡遍。所以平時(shí)我們用到的靜態(tài)選擇器就不會(huì)出現(xiàn)這個(gè)警告。因?yàn)樵诰幾g期間竹握,這些信息都已經(jīng)確定画株。
如:
[_renderer performSelector:@selector(someMethod)];
- (void)someMethod{
//code
}
而使用 [_renderer performSelector: NSSelectorFromString(@"release")]; 時(shí)ARC并不知道該方法的返回值是什么,以及該如何處理啦辐?該忽略谓传?還是標(biāo)記為 ns_returns_retained 還是 ns_returns_autoreleased ?
解決辦法
1.使用函數(shù)指針方式
SEL selector = NSSelectorFromString(@"release");
IMP imp = [_renderer methodForSelector:selector];
void (*func)(id, SEL) = (void *)imp;
func(_renderer, selector);
具體過程可以參考這篇文章:http://www.reibang.com/p/a9569a9c9a63
反正我試試了他的上面的方法,但是沒有任何效果
在這里我說下自己的見解:
項(xiàng)目采用iOS-ARC模式芹关,系統(tǒng)在進(jìn)入下一個(gè)控制器后返回上一個(gè)控制器時(shí)會(huì)自動(dòng)調(diào)用#pragma mark - lifeCycleMethod
dealloc方法里的release续挟,不用程序員自己再次手寫release代碼,若是寫了反而會(huì)崩潰侥衬,直接在
#pragma mark - lifeCycleMethod
-(void)dealloc {
?if(_renderer!=nil) {?
// [_renderer release];
// [_renderer performSelector:releaseSelector()];
_renderer = nil;
}
就可以了诗祸,注釋的地方不要加上去,謝謝??浇冰,最后直接讓控制器里的類_renderer = nil就可以了;贬媒,不要問為什么,因?yàn)橄到y(tǒng)已經(jīng)自動(dòng)幫我們r(jià)elease了肘习,之前一直用[_renderer performSelector:releaseSelector()];
////ARC下手動(dòng)release
static SEL releaseSelector(){
return NSSelectorFromString(@"release");
}
這里的release實(shí)在是畫蛇添足际乘,慚愧。
若是你用的是MRC模式:
就需在
#pragma mark - lifeCycleMethod
-(void)dealloc {
if(_renderer!=nil) {
[_renderer release];
_renderer = nil;
? [super dealloc];
}
最后ARC下的performSelector may cause a leak because its selector is unknown解決辦法是:
只是對http://www.reibang.com/p/2ff327a748d8
的崩潰的修復(fù)F濉2焙!