如何释放包含引用其父级的视图的视图控制器

Mik*_*ike 1 iphone memory-management objective-c uiviewcontroller didreceivememorywarning

这是一个有趣的问题.我有一个视图控制器,我们称之为MyViewController.其中一个成员是自定义视图,我们称之为MyCustomView.MyCustomView还具有对其父MyViewController的引用,因为MyViewController用作自定义视图的委托.卸载MyViewController时出现问题,比如由于内存警告.这是发生的事情:

首先,为MyViewController调用viewDidUnload.它看起来像这样:

- (void)viewDidUnload {
[super viewDidUnload];
    self.myCustomView = nil;
    self.someData = nil;
    ...
}
Run Code Online (Sandbox Code Playgroud)

当self.myCustomView = nil被执行时,它会触发myCustomView被释放.MyCustomView的dealloc例程看起来像这样:

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

回想一下,委托是MyViewController.如果首先发布MyCustomView,这不会有问题,因为MyViewController的引用计数大于1,但在这种情况下,MyViewController已经没有其他引用了.这会导致MyViewController被释放,即调用dealloc例程,如下所示:

- (void)dealloc { 
    [myCustomView release];
    [somedata release];
    ...
    [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,MyViewController的成员,即"somedata"在MyViewController的viewDidUnload例程完成之前就会被释放.随着MyViewController和MyCustomView的dealloc例程完成,我们回到完成viewDidUnload例程,我们到达该行

self.somedata = nil;
Run Code Online (Sandbox Code Playgroud)

现在,有些数据不是零,但它的价值已经被释放了!这会导致异常.

这似乎是引用计数中的一个关键缺陷.你如何处理这样的对象中的双向引用,导致彼此被释放?

一个答案是始终在dealloc例程中将成员设置为nil.我不喜欢那个答案.这是一项额外的工作,大部分时间都不需要.另一个答案是重新排列viewDidUnload的顺序,以便可能具有向后指针的子对象的释放总是在最后发生.我也不喜欢这种解决方案,有时甚至可能都无法工作.

你是如何解决这个问题的?

Tom*_*ift 5

代表成员通常不参考计数.通常声明是:

@property(nonatomic, assign) id<UITableViewDelegate> delegate
Run Code Online (Sandbox Code Playgroud)

如果你让你的代表这样你就不会有问题.它应该是安全的,因为父视图控制器只与子视图一样长 - 是吗?