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

185 Views Asked by At

I was searching crash logs of my app, and I've seen this (which occured quiet a few times, not just once or twice):

enter image description here

As seen above, notification center posted a memory warning notification, and it was somehow forwarded to a CALayer. I've also seen instances of didReceiveMemoryWarning: messages sent to other deallocated objects such as UIImageViews or even private _UINavigationBarBackground objects, when zombies were enabled on my debugger, too, crashing my app. Why would this happen?

2

There are 2 best solutions below

1
Reuben Scratton On BEST ANSWER

NSNotificationCenter only keeps weak references to observers.

What's probably happening is that you have one ore more objects somewhere that register for UIApplicationDidReceiveMemoryWarningNotification, but which never unregister (thats a bug). Since NSNotificationCenter only keeps weak references to those objects it doesn't notice when they are dealloc'd and their memory is reused for other objects such as CALayer etc, which do not implement a method named didReceiveMemoryWarning.

0
Nick On

This seems like a memory management issue. Typically, the memory warning would be sent to a currently-existing UIViewController, which lives at some hypothetical location X in memory.

But at runtime, instead of finding your UIViewController at location X as expected, it found some other object, like a random CALayer or UIImageView, which does not know how to respond to didReceiveMemoryWarning:. This results in the crash you're seeing.

Does your project use ARC? Enable it if its not already, that should reduce the frequency of these errors. If you're using manual retain/release, it is likely there is some error in your implementation.

If you have any code that does funny things with memory, or any code that does hacky things with view controller transitions, those are possible culprits, I'd post that code.

Also, try manually sending a memory warning to your app as soon as it is done starting up, to see if the issue manifests immediately, or if the app needs to run for a while before it occurs.