如果对象将要被销毁,为什么我们在dealloc中将委托设置为nil?

时间:2013-12-18 09:13:05

标签: ios objective-c delegates

-(void) scrollViewDidScroll:(UIScrollView *)scrollView
{
    PO(NSStringFromCGPoint(self.tableView.contentOffset));
    PO(NSStringFromUIEdgeInsets(self.tableView.contentInset));

    while(false);
}

-(void)dealloc
{
    PO(NSStringFromClass([self class]));
    PO(@"Deallocated");
    self.tableView.delegate=nil;
}

这里我需要设置self.tableView.delegate = nil以避免错误。

我知道,从我之前的问题来看,当委托被销毁时,self.tableView.delegate不会自动变为nill。那是因为委托的类型是分配引用而不是弱引用。

但是,self.tableView呢?

唯一强烈引用self.tableView的是它的超级视图,由self和self itsef拥有。

因此,当self被销毁时,self.tableView也应该被销毁,这意味着self.tableView.delegate也将被删除。

那么为什么我需要设置self.tableView.delegate=nil;

4 个答案:

答案 0 :(得分:9)

在许多情况下,您需要将委托设置为nil。在你的情况下,tableView可以被一些外部类引用,并且在你的类dealloc方法之后不会被销毁。并将继续调用其委托方法导致崩溃。 有几个类在另一个线程中工作(例如NSURLConnection)。即使您释放它,它也可以继续调用委托方法,因为它保留在另一个线程中。

答案 1 :(得分:5)

如果您持有对self.tableView的唯一引用,则无需将委托设置为nil。

唯一需要将委托设置为nil的情况,如果是另一个类将您的类作为委托,因为如果您的类被销毁,那么其他类将查找您的类来实现某些方法,以及您的调用不会在那里。

答案 2 :(得分:0)

假设我们有一个 SpriteKit scene,您有gesture recognizer并设置了delegate

然后,dealloc scene及其recognizer controller

如果在此过程中delegate中调用了scene方法,则会导致崩溃

答案 3 :(得分:-1)

实际上这不是必需的。我们这样做是为了避免形成保留周期。我们不应该创建具有强引用的委托。如果您不小心创建了具有强引用的委托,则父和子都不会被释放。在那种情况下,dealloc本身不会被调用。所以没有必要。