Objc memory crash with autorelase
I have been hunting all over my code and can't find the source of this crash: I am trying to decode an object with an NSKeyedUnarchiver and it crashes on it every time and says:
*** __NSAutoreleaseFreedObject(): release of previously deall开发者_如何转开发ocated object (0x1008ad200) ignored
*** __NSAutoreleaseFreedObject(): release of previously deallocated object (0x1008ab200) ignored
*** __NSAutoreleaseFreedObject(): release of previously deallocated object (0x1008a8c00) ignored
Ha my bad the reason why initWithCoder was not getting called was it was having issues with the [super initWithCoder:]; This is still driving me crazy. I looked and the pointers and the NSData objects are what are going wrong:
vertices = malloc(size_point3D * vertexCount);
textureCoords = malloc(size_point2D * textureCount);
normals = malloc(size_point3D * normalCount);
faces = malloc(sizeof(GLuint) * faceCount);
NSData *vertexData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"vertices"]];
NSData *textureData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"textureCoords"]];
NSData *normalData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"normals"]];
NSData *faceData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"faces"]];
memcpy(vertices, [vertexData bytes], sizeof(point3D) * vertexCount);
memcpy(textureCoords, [textureData bytes], sizeof(point2D) * textureCount);
memcpy(normals, [normalData bytes], sizeof(point3D) * normalCount);
memcpy(faces, [faceData bytes], sizeof(GLuint) * faceCount);
[vertexData release];
[textureData release];
[normalData release];
[faceData release];
I have tried retaining everything in this part (even the string) but it does not help.
This was a hard one to solve partly because debugging memory behaves inconsistently.
I have 2 classes JGStaticModel
and JGModel
. For some reason, the unarchiver would pick one of those at random so sometimes initWithCoder
was sent to JGModel
and not JGStaticModel
. This led me to think it was not being called. Also since their structure is slightly different it had issues and crashed. The reason why I got the autorelease problem was I patched some memory problems in JGStaticModel
but not JGModel
so it would crash on the memory because I had not fixed it there.
Thanks for all the help!
Try turning on NSZombieEnabled, this should help you track down the problem.
If neither tools (Run -> Run with Performance tools) and NSZombiesEnabled helps, you can override - (id)retain and - (void)release methods of the class that caused the exception. Call super implementation and log retain/release. You can break in this methods to see the call stack. This way isn't beautiful, however, it helped me few time to figure out where was an extra release/autorelease call
This problem is very easy to solve with the solution given here.
The relevant part is:
If an environment variable named "NSAutoreleaseHaltOnFreedObject" is set with string value "YES", the function will automatically break in the debugger
精彩评论