您是应该使用委托还是在类本身中将委托设置为nil

时间:2009-07-01 23:09:42

标签: objective-c memory-management delegates

如果A类正在使用B类而A类是B类的委托,那么如果在B类的dealloc中将委托设置为nil,那还可以吗?我已经看到代码通常会将代理重置为类A的dealloc中的nil,但不确定这样做的真正区别。

e.g。这是通常的方式:

// somewhere in class A

- (void) someFunc {
  self.b = [[B alloc] init];
  self.b.delegate = self;
}

- (void) dealloc {
  self.b.delegate = nil;
  [self.b release];
}

3 个答案:

答案 0 :(得分:15)

是的,您应该在classA的dealloc中将classB的委托属性设置为nil。

这不是内存管理问题,因为委托属性应该标记为assign而不是retain,以避免保留周期(否则将永远不会调用dealloc)。问题是否则classB可能会在发布后给classA发消息。

例如,如果classB有一个delagate调用说“被隐藏”,并且classB在classA之后被释放,它会向已经被释放的classA发送消息,导致崩溃。

请记住,你不能总是保证dealloc命令,特别是如果它们是自动释放的。

所以是的,在classA的dealloc中取出委托属性。

答案 1 :(得分:9)

据我所知,它是(分配)一个委托的最佳实践,这样你就可以避免对这种情况的保留计数进行循环引用。如果您已正确设置属性,即:

@property (assign) id<BDelegate> delegate;

你不必在dealloc中执行任何内存管理,因为当你调用self.b.delegate = self时,保留计数不会被碰撞; - 与使用(保留)或(复制)

不同

有意义吗?将委托设置为nil会很好,但最重要的是什么?

答案 2 :(得分:5)

首先,一些观察......

  1. 您忘记在自己的dealloc方法结束时致电[super dealloc]
  2. 由于'a'创建了'b',并且如果没有其他对象保留'b',那么-dealloc中的委托就没有意义了,因为'b'无论如何都要被销毁。如果其他对象可能引用'b'(意味着它可能比'a'更长),则将委托设置为nil。
  3. 对象'b'应该是在其自己的-dealloc 中处理其委托的那个。 (通常,委托人不保留代表。)
  4. 避免在-init ...和-dealloc方法中使用属性 - Apple不鼓励这样做,并且有充分的理由。 (它不仅会产生意想不到的副作用,而且还会导致更严重,更严重的问题。)
  5. 当您不需要无形地添加额外的工作时,使用属性(通过点语法)。例如,self.b.delegate = self相当于[[self getB] setDelegate:self] - 它只是语法糖,使它看起来像你直接访问ivar,但实际上并非如此。
  6. 使用属性而不了解它们的作用会导致麻烦。如果self.b保留该值(该属性设置为“assign”),则表示您手上有内存泄漏。
  7. 以下是我可能会写的:

    - (void) someFunc {
      b = [[B alloc] init];
      b.delegate = self; // or [b setDelegate:self];
    }
    
    - (void) dealloc {
      b.delegate = nil;
      [b release];
      [super dealloc];
    }