登录时,我通过VC1的segue调用了VC2
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString: @"embeddedVC2"]) {
self.VC2 = [segue destinationViewController];
self.VC2.delegate = self;
}
}
我在VC1中有dealloc
-(void)dealloc{
self.VC2.delegate=nil;
}
VC2中的委托声明为(nonatomic,assign)
在VC2中,我正在执行下载操作,完成后,我在打电话
[self.delegate downloadFinish:self.downloadData];
问题在于,当下载完成时,将调用VC1中的dealloc,并使VC2中的委托无效。因此,委托为nil,并且[self.delegate downloadFinish:self.downloadData];不起作用。
如果我在VC1
self.VC2.delegate=nil
方法中删除了dealloc
,则出现异常在行:
[self.delegate downloadFinish:self.downloadData];
消息发送到已释放实例:由于VC1已释放,我对此无能为力。
处理这种情况的正确方法是什么?
注意:仅当我再次重做该过程时,才会发生这种情况。
情况1:登录-> VC1-> VC2正常,代理通知我下载完成
情况2:VC1中没有dealloc方法:
登录-> VC1-> VC2->注销->登录-> VC1-> VC2(轰)崩溃消息发送到已释放实例
情况3:在VC1中具有dealloc并在其中具有self.VC2.delegate = nil:
登录-> VC1-> VC2->注销->登录-> VC1-> VC2没有任何反应,因为委托设置为nil
我尝试使用Zombie乐器,但我一点都不了解。我对长堆栈跟踪感到困惑,迷失了看参考计数并保留计数编号。如果需要的话,我可以将堆栈放到仪器中。
编辑:
我将委托更改为
nonatomic
和weak
,并删除了dealloc
方法。当我通过segue加载
VC2
时,VC2委托在viewDidLoad
中并不为零,但在下载完成时变成了nil
,此时我仍在VC2中。我不知道是什么使代理人无效,因为我没有搬到另一个VC。 最佳答案
确保您推送了VC,显示了VC或将其添加为childViewController,这样就不会释放父对象。否则,例如,如果使用选项卡,则需要确保VC1永远不会设置为nil。
如果您花费太多时间尝试解决它,我将重写您将VC添加到层次结构中的方式。
关于ios - 如何为案例设置委托(delegate):消息发送到已释放实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37601347/