自定义dealloc和ARC(Objective-C)


208

在我的小iPad应用程序中,我具有使用观察者的“切换语言”功能。每个视图控制器在其运行期间向我的观察者注册viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [observer registerObject:self];
}

当用户单击“更改语言”按钮时,新语言将存储在我的模型中,并通知观察者并调用updateUi:其已注册对象上的选择器。

这非常有效,除了在TabBarController中具有视图控制器时。这是因为在加载选项卡栏时,它会从其子控制器中获取选项卡图标,而无需初始化视图,因此viewDidLoad:不会调用它,因此这些视图控制器不会收到语言更改通知。因此,我将registerObject:调用移到了init方法中。

回到我以前viewDidLoad:向观察员注册时,我曾经viewDidUnload:注销过。由于我现在正在注册init,因此取消注册非常有道理dealloc

但是,这是我的问题。当我写:

- (void) dealloc
{
    [observer unregisterObject:self];
    [super dealloc];
}

我收到此错误:

ARC禁止显式发送消息“ dealloc”

由于我需要致电[super dealloc]以确保正确清理超类,但是ARC禁止这样做,所以我现在陷入困境。当我的物体快要死时,还有另一种方法来通知我吗?


附带说明-这种情况可能会导致内存泄漏,这不会在“泄漏”工具中显示。如果dataModel保留了对观察者的引用(这是ARC下的默认值,即使对于ivars),则将不会调用dealloc,因为保留计数将大于零。因此,您可能必须手动注销观察者的注册,才能首先调用dealloc。
BłażejCzapp

我为左右手选项实现了类似的功能。需要消息的唯一VC是当前显示的VC。其他人则在viewDidLoad或viewDidAppear中查看模型以对接口进行更改。也许这样的事情会更好。
Doug Watkins 2015年

@BlazejCzapp,因为他使用的是UITabBarController,并且说UITabBarController将始终持有对已注册控制器的引用(就像我猜想的那样,“子”控制器就是这种情况),内存泄漏仍然会成为问题吗?我看不到何时分配注册控制器。谢谢
Objectif

Answers:


419

使用ARC时,您根本不需要[super dealloc]显式调用-编译器会为您处理它(如Clang LLVM ARC文档第7.1.2章中所述):

- (void) dealloc
{
    [observer unregisterObject:self];
    // [super dealloc]; //(provided by the compiler)
}

4
如果视图持有对观察者的引用,而观察者拥有对视图的引用,则我们有一个循环引用。因此,视图的引用计数大于0,并且dealloc从不调用。调用[observer unregisterObject:self]dealloc 是否有意义?我想念什么?
user443854 2015年

多数民众赞成想要工作。导致观察者本身持有对控制器的引用。首先将阻止dealloc的调用
哈桑
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.