So the app was crashing with no stack trace or any exceptions, and I could replicate this crash every time. My first thought was that it has to be a double release, after running zombies for 10 minutes, I was not able to get the app to crash, not even once.
After looking at Allocations I noticed a huge jump in the size of allocated objects when the method gets called. So I ended up having an @autoreleasePool inside the for loop. this autorelease pool fixed the crash; but how can I confirm that this really was an out of memory issue? (didRecieveMemoryWarning did not get called at any time before the crash)
Why does autoreleasePool fix the problem?
Why doesn’t didRecieveMemoryWarning get called? Is it because application runs out of memory before we get to the end of the current runloop?
- (void)doSomething
{
for (Item *item in self.items)
{
@autoreleasepool
{
// A bunch of initializations here that take a lot of memory
}
}
}
Use Instruments to monitor allocations and see if it rises without the autorelease pool.
If the crash happens particularly fast or you are blocking the queue upon which the memory notification happens, you won’t see the notification.
Autorelease is fixing the issue most likely because there are a ton of autoreleased objects created as a part of your initializations. The pool won’t be drained until the loop is exited.