登录时,我通过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乐器,但我一点都不了解。我对长堆栈跟踪感到困惑,迷失了看参考计数并保留计数编号。如果需要的话,我可以将堆栈放到仪器中。

编辑:

我将委托更改为nonatomicweak,并删除了dealloc方法。

当我通过segue加载VC2时,VC2委托在viewDidLoad中并不为零,但在下载完成时变成了nil,此时我仍在VC2中。我不知道是什么使代理人无效,因为我没有搬到另一个VC。

最佳答案

确保您推送了VC,显示了VC或将其添加为childViewController,这样就不会释放父对象。否则,例如,如果使用选项卡,则需要确保VC1永远不会设置为nil。

如果您花费太多时间尝试解决它,我将重写您将VC添加到层次结构中的方式。

关于ios - 如何为案例设置委托(delegate):消息发送到已释放实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37601347/

10-13 06:26