为什么 iOS 向释放的对象发送内存警告,导致我的应用程序崩溃?

Why is iOS sending memory warning to deallocated objects, causing my app to crash?

我正在搜索我的应用程序的崩溃日志,我看到了这个(它安静地发生了几次,不仅仅是一两次):

如上所示,通知中心发布了一条内存警告通知,并且以某种方式转发给了 CALayer。我还看到 didReceiveMemoryWarning: 消息发送到其他已释放对象的实例,例如 UIImageViews 甚至私有 _UINavigationBarBackground 对象,当在我的调试器上启用僵尸时,也会使我的应用程序崩溃。为什么会这样?

这似乎是一个内存管理问题。通常,内存警告将发送到当前存在的 UIViewController,它位于内存中某个假设的位置 X。

但是在 运行 时间,它并没有像预期的那样在位置 X 找到你的 UIViewController,而是找到了一些其他对象,比如随机的 CALayerUIImageView,它不知道如何回应 didReceiveMemoryWarning:。这会导致您看到的崩溃。

您的项目是否使用 ARC?如果尚未启用它,那应该会减少这些错误的频率。如果您使用的是手动 retain/release,则可能是您的实施存在一些错误。

如果您有任何代码对内存做有趣的事情,或者任何代码对视图控制器转换做一些骇人听闻的事情,这些都是可能的罪魁祸首,我会 post 那个代码。

此外,请尝试在您的应用启动后立即手动向其发送内存警告,以查看问题是否会立即显现,或者应用是否需要 运行 一段时间才能出现.

NSNotificationCenter 仅保留对观察者的 weak 引用。

可能发生的情况是,您在某处有一个或多个对象注册了 UIApplicationDidReceiveMemoryWarningNotification,但从未取消注册(这是一个错误)。由于 NSNotificationCenter 只保留对这些对象的弱引用,因此当它们被释放时它不会注意到它们,并且它们的内存被其他对象重用,例如 CALayer 等,这些对象没有实现名为 didReceiveMemoryWarning 的方法。