释放对象时的奇怪行为

Posted

技术标签:

【中文标题】释放对象时的奇怪行为【英文标题】:Strange behaviour while deallocation of an object 【发布时间】:2013-01-23 17:14:57 【问题描述】:

我有一个视图,它是 UIWebView 的子类。它有一个名为 Contact属性,它是一个托管对象。该视图使用模板引擎创建带有对象的 html,然后加载到 UIWebView。我认为在视图本身中监视对象会是一个更好的主意,这样每当对象发生变化时,视图就会自动刷新。因此,在视图本身中观察托管对象的某些属性。然后为了避免通知合并,我已经完成了重新加载

[self performSelector:@selector(refresh) afterDelay:0 ].

它会在发现更改时自动刷新 webview,但也会出现一些奇怪的崩溃。崩溃显示 [MyWebView 保留] 消息已发送到已释放对象。我知道我已经正确删除了 dealloc 方法中的观察值。但是,似乎 dealloc 会在一段时间后被触发。我有一个与发布视图有关的奇怪问题。视图会停留一段时间,尽管视图控制器已经释放,然后在 2/3 秒后释放。这真的很奇怪。我认为崩溃是因为这个。

请建议我任何想法。我很高兴听到你的建议。肯定有问题,如果有人能指出我真的很感激。

【问题讨论】:

尝试在解除分配之前将所有可能的委托(来自 WebView 等)设置为 nil。有时委托方法可以在对象释放后启动。 查看这篇文章,了解为什么 nil 可能是您需要的更多信息:***.com/a/1564419/135557 你试过将其中一个引用设置为弱吗?最好是独立于对象的那个,所以即使你的消息被发送,给 nil 的消息也可以。 【参考方案1】:

如果使用不当,使用委托设计模式可能会导致 EXC_BAD_ACESS KERN_INVALID_ADDRESS 崩溃。如果您有在使用委托设计模式的后台线程中运行的处理,在您将 SELF 设置为委托的对象中,您必须通过将委托引用设置为nil,或者对象可能会尝试使用委托设计模式回调您已释放的对象。所以如果你的对象中有这样的东西。

[_xmlParser setDelegate:self];

即使在 ARC 下,您也应该始终有一个 dealloc 方法,以防止在您的对象在仍在工作的同时被破坏的情况下发生崩溃的可能性。在工作时破坏您的对象是很常见的。想象一个 UIViewController 显示来自互联网的图像。如果你有一个 FetchImage 类,它使用委托设计模式来查找图像,然后在查找完成时调用对象上的例程,那么当 FetchImage 对象仍在工作时,用户很容易进出你的 UIViewController在后台线程上。测试时您可能不会注意到这一点,但如果您有数百名用户,他们中的一些人会注意到,因为当您的对象尝试调用 SELF 引用上的方法时,应用程序会崩溃。

如果您的对象使用委托设计模式,请始终清理:

#pragma mark - dealloc - cleanup delegate references to prevent callbacks into deallocated objects (EXC_BAD_ACCESS / KERN_INVALID_ADDRESS)

- (void)dealloc

    [_xmlParser setDelegate:nil];
    // for non ARC based code you would also call: [super dealloc]; 

搜索项目中的每个类,如果您设置了 setDelegate:self 或 delegate = self,那么如果您没有如上所述的 dealloc 清理方法,那么您的用户很可能会遇到您的应用程序的竞争条件崩溃。如果您没有 dealloc,请添加它,即使您在测试时从未看到崩溃。 -rrh

【讨论】:

或者您可以将委托设置为“弱”属性(或至少分配给非 ARC 代码)...

以上是关于释放对象时的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

当原始指针和唯一指针都引用同一个对象时,如何避免双重释放?

Unity:当我释放动作输入时,玩家行为怪异

UITableViewController 中的 iPhone 奇怪行为

ARC奇怪的双重释放?

过度释放导致的奇怪的核心数据错误?

释放对象后调用方法?