64

也许这是一个不好的做法,但是从我阅读的文档中,我得到了在某些情况下在 viewDidLoad 方法中初始化对象并在 viewDidUnload 中将其设为 nil 的建议。

例如,如果您有添加观察者之类的东西

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(filterready:)
                                                 name:@"filterReady"
                                               object:nil];

现在我没有删除观察者的方法,但是每次显示视图时都会调用 viewDidLoad,这会导致一段时间后运行多个观察者,然后多次调用选择器。

我可以通过将一些清洁器移入 viewDidDisappear 方法来解决这个问题,但现在我怀疑我是否做对了。

在我的示例中,我有多个控制其子导航的导航控制器,但从未为它们调用 dealloc,即使它们没有被引用

4

4 回答 4

110

您应该使用 - (void)didReceiveMemoryWarning and - (void)dealloc方法。

在 iOS 6 中,UIViewController 的 viewWillUnload 和 viewDidUnload 方法现已弃用。如果您使用这些方法来释放数据,请改用 didReceiveMemoryWarning 方法。如果不使用视图控制器的视图,您也可以使用此方法释放对视图控制器的视图的引用。在执行此操作之前,您需要测试视图是否不在窗口中。

所以你应该先检查你的视图是否在窗口中,然后在窗口中移除你的观察者didReceiveMemoryWarning

于 2012-09-26T14:04:08.540 回答
16

首先,即使viewDidUnload没有被弃用,您也必须在viewDidUnloadAND中取消注册该通知dealloc。即使在 iOS 6 之前,viewDidUnload大多数情况下也不会调用;仅在内存不足的情况下。所以如果你只是把它放进去viewDidUnload而不是dealloc之前,它就不会被取消注册,它可能会在它被释放并收到通知时崩溃。所以你必须先把它放进去dealloc,它才能正常工作。

其次,如果你之前做的正确,你不需要做任何额外的事情来让它在 iOS 6 中正常工作。iOS 6 中唯一的区别是视图不再被卸载(即使在内存不足的情况下)。因此,当您没有遇到内存不足的情况时,它与 iOS 5 中的情况相同。由于视图没有被卸载,viewDidLoad只会被调用一次,所以你的通知只会被注册一次。它将在 中取消注册dealloc,因为您必须将其放入它才能正常工作。

于 2012-10-31T00:04:32.130 回答
10

亚历克斯的回答很好。但我喜欢适当的配对。出于这个原因,除非视图需要在它甚至没有看到时被通知,否则我通常会在 viewWillAppear 和 viewDidDisappear 添加通知

于 2012-10-29T11:30:50.927 回答
5

为什么不直接删除 DEALLOC 函数中的观察者呢?如果您使用 ARC,请不要调用 [super dealloc]

如果您查看控制器 dealloc 函数没有被调用,那么您需要找出原因。也许你有一个在 ViewController 上运行的 NSTimer,当你弹出视图时,这会导致 dealloc 不会被调用。或者视图被保留在其他地方。

于 2012-09-26T13:56:28.137 回答