If you have ever asked how can I debug releasing/alloc issues in objective-c, you will have came across these environment settings that can help track the problem down:
@Kay is correct; the malloc history is showing two allocations at the specified address; one that has been allocated and freed and one that is still in play.
What you need is the backtrace of the call to retainCount
on the CALayer
that has already been released. Because you have zombie detection enabled, amongst other memory debugging things, it may be that the deallocation simply has not & will not happen.
Mixing malloc history with zombie detection changes the runtime behavior significantly.
I'd suggest running with zombie detection in Instruments. Hopefully, that'll pinpoint the exact problem.
If not, then there is a breakpoint you can set to break when a zombie is messaged. Set that breakpoint and see where you stop.
OK -- so, CoreAnimation is using the retain count for internal purposes (the system frameworks can get away with this, fragile though it is).
I think the -1 is a red herring; it is likely that zombies return 0xFF....FFFF as the retain count and this is rendered as -1 in Instruments.
Next best guess; since this is happening in a timer, the over-release is probably happening during animation. The CoreAnimation layers should handle this correctly. There is an over-release of a view or animation layer container in your code that is causing the layer to go away prematurely.
Have you tried "Build and Analyze"? Off-chance it might catch the mismanagement of a view somewhere.
In any case and as an experiment, try retaining your view(s) an extra time and see if that makes this problem stop. If it does, that is, at least, a clue.
(Or it might be a bug in the system frameworks... maybe... but doubtful.)
Finally, who the heck is calling retainCount
?!?!? In the case of CoreAnimation, it is possible that the retainCount
is being used internally as an implementation detail.
If it is your code, though, then the location of the zombie call should be pretty apparent.
I am no expert, but if you take a look at the first line in block 3:
ALLOC 0x4dbb170-0x4dbb19f [size=48]:
While in the other two outputs a memory block of size 18 at 0x4dbb160-0x4dbb171 was allocated and freed. I assume the old object was freed and there is a new object residing at this memory address. Thus the old instance at 0x...b160 is not valid any longer.