I have just be开发者_开发知识库en through a client project initially coded by us then abused by them! And we are getting a strange crash, which is consisten on each mac individually but inconsistent between the team or after a reload/restart of Xcode/OSX.
The problem is one I have come across before when I havent been cleaning up objects properly, but I have been through static analyser and am still struggling.
The crashes always seem to occur because objects we have created in the VC are getting overwritten by others therefore changing their type so valid method calls are being thrown as exceptions.
For example:
NSNumber *test1;
-(void)viewDidLoad {
test1 = [NSNumber numberWithInteger:7];
}
-(void)someOtherMethod {
NSLog(@"what was test? %@", [test stringValue]);
}
This is currently throwing an unrecognized selector exception during the NSLog as hovering over test1 tells me is is of type NSURLRequestInternal, if I restart Xcode it will probably be somewhere else!!
How can I debug/solve this!?!?
That should crash every time.
Let's look at the code.
test1 = [NSNumber numberWithInteger:7];
This creates a NSNumber and assigns it to the instance. However, the NSNumber is scheduled for deallocation as soon as the main event loop is run.
NSLog(@"what was test? %@", [test stringValue]);
This, presumably, is being run after the main event loop has had a swing. At this point, test (and I assume this should be test1) is pointing to a dangling pointer. Accessing it will crash.
There is no substitute to reading Apple's documentation on memory management: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
This will explain what you need to know. But basically, you should be using [[NSNumber alloc] initWithInteger:7]
or retain it (possibly using property syntax) instead.
But unless you read Apple's documentation on the subject, you're going to be chasing memory bugs forever.
you forgot to retain test1 so it gets autoreleased, hence the crash
try using NSZombieEnabled for debugging this kind of stuff.
test1 = [NSNumber numberWithInteger:7];
should either be
test1 = [[NSNumber numberWithInteger:7] retain];
or (better)
test1 = [[NSNumber alloc] initWithInteger:7];
numberWithInteger:
returns an autoreleased object, so by the time someOtherMethod
is called, the object that test1
points to has been deallocated.
精彩评论