Ios 如何为案例设置委托:发送到解除分配实例的消息

Ios 如何为案例设置委托:发送到解除分配实例的消息,ios,objective-c,delegates,Ios,Objective C,Delegates,当我登录时,我从VC1通过segue调用VC2 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if ([[segue identifier] isEqualToString: @"embeddedVC2"]) { self.VC2 = [segue destinationViewController]; self.VC2.delegate =

当我登录时,我从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中的委托声明为(非原子,赋值)

在VC2中,我正在执行一个下载操作,当它完成时,我正在呼叫

  [self.delegate downloadFinish:self.downloadData];
问题是,当下载被找到时,VC1中的dealloc被调用,它使VC2中的委托为nil。因此,委托为nil,并且[self.delegate downloadfish:self.downloadData];不起作用

如果在VC1
dealloc
方法中删除self.VC2.delegate=nil,则会得到异常 在生产线上:

   [self.delegate downloadFinish:self.downloadData];
发送到解除分配实例的消息:因为VC1已解除分配,我无法对其执行任何操作

处理这种情况的正确方法是什么

注意:仅当我再次执行该过程时才会发生这种情况

案例1:登录->VC1->VC2工作正常,代理通知我下载完成

案例2VC1中无解除锁定方法:

登录->VC1->VC2->注销->登录->VC1->VC2(boom)崩溃消息发送到解除分配的实例

案例3在VC1中使用dealloc,在其中使用self.VC2.delegate=nil:

登录->VC1->VC2->注销->登录->VC1->VC2什么都不会发生,因为委托被设置为零

我试着用僵尸乐器,但我一点也不懂。我被长长的堆栈跟踪弄糊涂了,看不清引用计数和保留计数。如果你需要的话,我可以把stacktract贴在仪器上

编辑:

我将委托更改为
非原子
,并删除了
dealloc
方法


当我通过segue加载
VC2
时,VC2委托在
viewdiload
中不是nil,而是在下载完成时变成
nil
,此时我仍然在VC2中。我想知道是什么原因使代理为零,因为我没有转移到另一个VC。

确保推送VC、呈现VC或添加为childViewController,这样家长就不会被解除分配。否则,如果您使用的是tabbar,您需要确保VC1永远不会被设置为nil


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

确保您推送VC、提交VC或添加为childViewController,这样家长不会被解除分配。否则,如果您使用的是tabbar,您需要确保VC1永远不会被设置为nil


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

委托属性应该是
weak
,而不是
assign
。如果我将其设置为weak,那么仍然需要在dealloc方法中将委托设为nil吗?@rmaddyNo,应该不需要设置它
dealloc
。但是如果你这样做了也不会有什么坏处。它为我解决了一个困惑(案例1和案例2),但委托是零。我还有关于案例3的问题。委托为零,即使我通过segue设置了它@RMADDY您应该开始一个新问题,包括尽可能多的细节(如调用堆栈等)。rmaddy已经回答了这个问题。委托属性应该是
weak
,而不是
assign
。如果我将其设置为weak,那么仍然需要在dealloc方法中将委托设为nil吗?@rmaddyNo,应该不需要设置它
dealloc
。但是如果你这样做了也不会有什么坏处。它为我解决了一个困惑(案例1和案例2),但委托是零。我还有关于案例3的问题。委托为零,即使我通过segue设置了它@RMADDY您应该开始一个新问题,包括尽可能多的细节(如调用堆栈等)。这个问题已经由rmaddy回答了。