繁体   English   中英

ARC:Dealloc释放委托之前,我可以将其从观察者列表中删除

[英]ARC: Dealloc releases delegate before I can remove it from observer list

我有一个标准的案例,为简单起见,假设有MyController及其MyModel。 这是MyModel的摘录:

@interface MyModel

  @property (nonatomic, weak) id<ModelObserver> *delegate;

@end

@implementation MyModel

- (id)initWithDelegate:(id<ModelObserver>)delegate
{
  self = [super init];
  if (self) {

    _delegate = delegate;

    // Adds observer for model load and changes
    [self addObserver:_delegate];
    ...
}

- (void)dealloc
{
  // Remove delegates and progress indicator
  [self removeObserver:_delegate];

@end

这是MyController的摘录

@interface MyController

@property (nonatomic, strong) MyModel *_myModel;

@end

@implementation MyController

- (void)commonInit
{
  _myModel = [[MyModel alloc] initWithDelegate:self];
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  if (self) {
    // Custom initialization
    [self commonInit];
  }
  return self;
}

@end

MyModel具有类型为id(指向MyController)的委托。 MyController具有强大的ivar _myModel。 MyController创建模型,并将自己作为委托传递给alloc。 MyModel扩展了MyBaseModel,并向观察者列表添加了一个委托(MyController),并获得有关列表模型更改的通知。 问题是,观察者MyController在[self removeObserver:_delegate]之前被释放。 能够将其从观察者列表中删除,因此有时稍后我会崩溃。

已经进行调试,并且在“ [self removeObserver:_delegate];”上停止执行时 MyController仍然存在(po _delegate打印出对象)。 但是,_delegate在进入[self removeObserver:_delegate]之后就为零,我的意思是param从内部为零。

更新如果我在dealloc中执行“ po _delegate”,我可以看到对象,所以它不是nil。 但是,一旦代码进入[self removeObserver:_delegate],它就为零,因此它不会作为参数传递给“ removeObserver:”。 但是,当我在调试时从“ removeObserver:”返回以取消分配时,_delegate不再为nil。

这大致是这里发生的情况:

  • 释放MyController实例后,其实例变量_myModel设置为nil ,这将导致调用-[MyModel dealloc]
  • 此时, _delegate实例变量尚未为nil ,但是访问委托返回的结果为nil因为指向对象的对象正在释放中。

(有关更详细的分析,请参阅在dealloc中弱属性设置为nil,但属性的ivar设置为nil 。)

观察弱属性通常很危险,因为模型无法控制何时释放该对象。

如果只想拥有与手动引用计数相同的行为,则可以将delegate属性声明为assign而不是weak 这意味着__unsafe_unretained实例变量,可以解决您的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM