views:

1461

answers:

2

i got an object and in that object i start my thread (for loading doing some url loading)

when i have a return of my data i call a selector to perform on the main thread.

works fine if i call it the first time , second time it crashes ( no specific error)

[NSThread detachNewThreadSelector:@selector(doThread:)
       toTarget:self
        withObject:@"lala"];

-(void) doThread:(NSString *)poststring {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


DataModelLocator *mydelegate = [DataModelLocator instance];
NSData *postData = [poststring dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSURL *url = [NSURL URLWithString:[mydelegate fwaservicepath]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

[request setURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
[request setHTTPBody:postData];

NSURLResponse *urlResponse;

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:nil];

if(data) {
 [self performSelectorOnMainThread:@selector(loadDidFinishWithData:)
         withObject:data 
      waitUntilDone:YES];
 //[self loadDidFinishWithData:data];
} else {
 [self performSelectorOnMainThread:@selector(loadDidFinishWithError:)
         withObject:data 
      waitUntilDone:YES];
}
[pool release];

} }

It crashes when i call the performSelectorOnMaintThread.. could it be that i it crashes on an singleton, when it got released?

A: 

You may want to post some more information about your problem (which of the two lines crashes, what you've figured out from debugging so far, etc.) so that we can offer you some better suggestions. Without knowing which line is giving you problems, I'll hazard a guess: from the sound of it, you might have an object somewhere that's getting cleaned up by the automatic garbage collection.

Where is the variable "data" coming from? If you're creating it in the header file as a private member variable, you might have something like:

NSSomeType *data = [NSSomeType builtInInitFunction];

A variable initialized like this will normally be autoreleased, but you probably want to make sure that the garbage collection retains the instance of that object. Try something like:

// Objects initialized with init are retained
NSSomeType *data = [[NSSomeType alloc] init];

// Objects that would normally be autoreleased can be marked as retain
NSSomeType *data = [[NSSomeType builtInInitFunction] retain];

I'm not sure how your code is structured, but be sure to add at least one release for every retain and init! I'm still pretty new to Objective-C, so it's a little bit like the blind leading the blind so take my advice with a grain of salt.

Check out the "More on Memory Management" section of Learn Objective-C for more info.

EDIT2: Clarified example code. Thanks to Evan (comments) for the help.

EDIT3: I agree with Brad. Consider removing the AutoRelease pool you have an handling your alloc/init/release yourself. I don't know enough about the NSURLConnection object to know this, but is your *data memory being marked as Autorelease? If so, you may need to initialize in a different way or use retain.

Step through your code in the debugger. Figure out A) exactly which line is crashing and then B) the values of all of your variables. If you're lucky, you'll notice one is nil.

Mark
The alloc acts as a retain, so adding an extra retain call will cause a leak (because the corresponding [data release] will decrement the retain count once, but it has been incremented by both the alloc and the explicit retain).
Evan DiBiase
But I do think you're on the right track, though; it's possible that data is getting garbage collected or released after the first call but before the second.
Evan DiBiase
+3  A: 

When dealing with threads, avoid autoreleased objects like the plague. The autorelease pools will be drained at nondeterministic times, causing fun crashes. Use alloc/init and release on all objects involved, making sure to retain all objects that you take in on methods that are called from another thread using performSelectorOnMainThread or detachNewThreadSelector.

Garbage collection on the Mac effectively solves these problems, but the iPhone is not going to have that any time soon.

Brad Larson
Also, since a lot of the methods in the frameworks create autoreleased objects you will need to create at least one autorelease pool per thread to avoid leaks (for long-lived threads drain often)
rpetrich