I have a Cocoa app with ARC enabled. I am using OS 10.8 and Xcode 4.4. The app sporadically crashes upon calls to CGLayerRelease, dumping messages like the following to console:
error for object 0x10a2d2000: entry for pointer being freed from death-row vanished
If I comment out the calls to CGLayerRelease the crashing stops. Do I need to call CGLayerRelease in ARC enabled projects? The documentation isn't very clear about this.
It is hard to post code for this because it is spread throughout a large file for a class that inherits from NSView. The class has a data member CGLayerRef layer;
. Then inside the drawRect function:
if (layer == nil) {
layer = CGLayerCreateWithContext(context, self.frame.size, NULL);
// draw some stuff into CGLayerGetContext(layer)
}
CGContextDrawLayerInRect(context, self.bounds, layer);
The class is also a delegate of its window and has the following function
- (void)windowDidEndLiveResize:(NSNotification *)notification {
if (layer) {
//CGLayerRelease(layer);
layer = nil;
}
[self setNeedsDisplay:YES];
}
Also inside a property setter
- (void)setPitch:(NSArray *)aPitch {
pitch = aPitch;
if (layer) {
//CGLayerRelease(layer);
layer = nil;
}
}
Now if I uncomment the calls to CGLayerRelease
then I sporadically get the crash mentioned above. I stress "sporadically" because it does not always happen.
Yes, you need to call CGLayerRelease() in ARC. The above assignments look correct, but I suspect you may have others. You're directly accessing your ivars, which is the #1 cause of these kinds of crashes. Do not access your own ivars except in init and dealloc. Create an accessor for setLayer:
that correctly releases the old one and creates a new one and always use that.
It's very possible that your CGLayer code is fine, and that it's something else like a CGPath that you're adding to the CGLayer. Move all your ivars to accessors. Otherwise you will be chasing these kinds of bugs forever.