I'm wondering what could cause this. I have several methods in my code that i call using performSelectorInBackground. Within each of these methods i have an Autoreleasepool that is being alloced/initialized at the beginning and released at the end of the method.
this perfectly works on iOS 3.1.3 / 3.2 / 4.2 / 4.2.1 but it fataly crashes on iOS 4.0 with a EXC_BAD_ACCESS Exception that happens after calling [myPool release].
After I noticed this strange behaviour I was thinking about rewriting portions of my code and to make my app "less parallel" in case that the client os is 4.0.
After I did that, the next point where the app crashed was within the ReachabilityCallback-Method from Apples Reachability "Framework".
well, now I'm not quite sure what to do.
The things i do within my threaded methods is pretty simple xml parsing (no cocoa calls or stuff that would affect the UI). After each method finishes it posts a notification which the coordinating-thread listens to and once all the parallelized methods have finished, the coordinating thread calls viewcontrollers etc...
I have absolutely no clue what could cause this weird behaviour. Especially because Apples Code fails as well.
any help is greatly appreciated!
The best way to detect zombies is:
- in the Groups and Files section, expand the Executables section and right click on your app name and choose Get Info
- select the Arguments tab on the top and then add a new entry in the Variables to be set in the environment section. Name the new variable to NSZombieEnabled and set its value to YES.
After this you will have information in console on which released objects you make calls.
Seem's like i've solved the Issue. The Problem was, that (as many of you suggested) I've overreleased an NSURL Object within a Method which calls
[NSString stringWithContentsOfURL:urlRequest encoding:NSUTF8StringEncoding error:&error];
I assume that
stringWithContentsOfURL autoreleases the NSURL object that i pass as a parameter.
after removing the release on
urlRequest the issue dissapeared. Still i think that it's very strange that different iOS Versions behave differently on that matter.
the whole method looked like this:
NSString *data = nil;
NSError *error = nil;
data = [NSString stringWithContentsOfURL:urlRequest encoding:NSUTF8StringEncoding error:&error];
//[urlRequest release]; //Crashes on iOS 4.0 / 4.1 later when autoreleasepool is being released.
Sounds like an autoreleased object created in the scope of that autorelease pool is being released somewhere it shouldn't be. Not sure why the behaviour differs with the version of the SDK; there must be an implementation difference somewhere that's causing the issue. Have you built the code using "Build and Analyze"? Does it suggest anything might be over-released?
I've noticed some strange behavior with
performSelectorInBackground also. I might be completely wrong on this, but in my case I've used:
[NSThread detachNewThreadSelector:@selector(blah) toTarget:self withObject:nil];
with better results. If, when you're in that method, you need to access the main thread (to update the UI for example), you can just:
[self performSelectorOnMainThread:@selector(blah2) withObject:nil waitUntilDone:false];