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的顺序,以便可能具有向后指针的子对象的释放总是在最后发生.我也不喜欢这种解决方案,有时甚至可能都无法工作.
你是如何解决这个问题的?
代表成员通常不参考计数.通常声明是:
@property(nonatomic, assign) id<UITableViewDelegate> delegate
Run Code Online (Sandbox Code Playgroud)
如果你让你的代表这样你就不会有问题.它应该是安全的,因为父视图控制器只与子视图一样长 - 是吗?