ARC and UIAlertView: unrecognized selector sent to instance
將cell作為代理慰丛,當cell被釋放卓囚,出現(xiàn)的crash問題。
1.NSObject* obj = [[NSObject alloc] init];
控制臺诅病,打印對象:
打印對象,會調用description方法锣夹,默認返回<類名: 地址>页徐。
來自博客:iOS 常見 Crash 及解決方案
2.背景:
在自定義TableViewCell類中:
點擊cell上的某個按鈕,彈出AlertView银萍。
點擊事件中变勇,初始化這個alertView,調用alertView自定義初始化方法(initWithFrame:delegate:self),傳遞self即Cell贴唇,設置代理搀绣。
在AlertView類中:
聲明協(xié)議,并有三個協(xié)議方法如rightBtnClicked:等
使用前設置代理戳气,在alertView链患,alloc的時候,設置的代理self.delegate = xxxCell
點擊如右邊的button瓶您,觸發(fā)事件
- (void)btnClicked:(UIButton *)btn?
{
? ? ? ? [self.delegate rightBtnClicked:btn] // crash麻捻,此時delegate已經(jīng)被釋放了
}
實際上就是cell對象已經(jīng)被釋放,即delegate被dealloc了呀袱。指針沒有置空,這時再訪問這個指針指向的內存夜赵,就會 Crash。
無法用if (nil = delegate)判斷delegate是否已經(jīng)被dealloc掉寇僧,因為被dealloc之后,delegate對象也不是空的兴蒸,這個時候delegate可能已經(jīng)是野指針了细办。
3.解決辦法。
可以在cellforrow里判斷蟹腾,在delegate是被釋放了的情況娃殖,重新賦值议谷,設置代理。
調用者在對象銷毀時未將delegate置為nil,delegate將變成野指針赴捞,而導致程序掛掉郁稍。設置nil。
weak恢着,assign。我們的delegate掰派,在arc中用weak
當時解決問題參考的博文:
1.ios - ARC and UIAlertView: unrecognized selector sent to instance - Stack Overflow
2.ios 自動內存管理 ARC - Aimy的個人空間 - 開源中國社區(qū)
原文如下:
今天在公司爆出一個 BUG,導致5000+crash.
大致是 UIKit 中的 delegate 訪問了已經(jīng)釋放了的界面,也就是使用了野指針導致 crash.
回來演示了一下發(fā)現(xiàn)
@property (nonatomic, assign) id delegate;//1
@property (nonatomic, weak) id delegate;//2
大部分的 UIKit 的 delegate 都是如1的聲明
因為 ios 在5之前是沒有 ARC 的,為了兼容所以寫的都是 assign
那么 assign 與 weak 有什么區(qū)別呢?
__strong NSString *yourString = [[NSString alloc] initWithUTF8String:"your string"];
__weak? NSString *myString = yourString;
yourString = nil;
__unsafe_unretained NSString *theirString = myString;
//現(xiàn)在所有的指針都為nil
weak的特性,如果指向的內存被釋放了,則自動指向 nil;
所以使用 weak 是不會有野指針的
而 assign 和unsafe_unretained,永遠指向某內存地址,如果該內存被釋放了,自己就會成為野指針
如下
__strong NSString *yourString = @"Your String";
__weak? NSString *myString = yourString;
__unsafe_unretained NSString *theirString = myString;
yourString = nil;
//現(xiàn)在yourString與myString的指針都為nil,而theirString不為nil,但是是野指針靡羡。
所以我們在使用 UIKit 中的 delegate 的時候,要避免響應 delegate 的VC,或者 View 之類的實例被提前釋放了,而導致 crash
而我們自己的 delegate 可以直接寫成 weak 的,既避免了循環(huán)引用,又不會產(chǎn)生野指針.
3.MRC下delegate 野指針問題 - James.Y - 博客園
在全局斷點中定位到出問題的點上略步,竟然是delegate回調的地方出現(xiàn)了問題!
if(self.delegate && [self.delegate respondsToSelector:@selector(test:)]) {
[self.delegate test:nil];
}