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

Boo*_*oon 13 delegates memory-management objective-c

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

这是通常的方式:

// somewhere in class A

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

- (void) dealloc {
  self.b.delegate = nil;
  [self.b release];
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*wis 15

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

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

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

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

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


Jos*_*osh 9

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

@property (assign) id<BDelegate> delegate;
Run Code Online (Sandbox Code Playgroud)

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

合理?将委托设置为nil会很好,但最重要的是什么?

  • 将委托设置为nil有一点,因为如果客户端试图调用不再存在的委托对象,它将不会崩溃,因为它被设置为nil. (3认同)

Qui*_*lor 5

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

  1. 您忘了[super dealloc]在自己的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"),则表示手上有内存泄漏.

这是我可能会写它的方式:

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

- (void) dealloc {
  b.delegate = nil;
  [b release];
  [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)