views:

43

answers:

2

I have an app that uploads to Google Spreadsheets via the GData ObjC client for Mac/iPhone. It works fine as is. I'm trying to get the upload portion on its own thread and I'm attempting to call the upload method on a new thread.

Look:

-(void)establishNewThreadToUpload {
    [NSThread detachNewThreadSelector:@selector(uploadToGoogle) toTarget:self withObject:nil];
}

-(void)uploadToGoogle {
    NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
    //works fine
    [helper setNewServiceWithName:username password:password];
    //works fine
    [helper fetchUserSpreadsheetFeed];
    //inside the helper class, fetchUserSpreadsheet feed calls ANOTHER method, which
    //calls ANOTHER METHOD and so on, until the object is either uploaded or fails
    //However, once the class gets to the end of fetchUserSpreadsheetFeed
    //control is passed back to this method, and
    [pool release];
    //is called.  The thread terminates and nothing ever happens.
}

If I forget about using a separate thread, everything works like it's supposed to. I'm new to thread programming, so if there's something I'm missing, please clue me in!

Thanks!

A: 

I've had this problem and I have a solution, however, the solution kind of makes me cringe as it works, but something smells about it... it seems like their should be a better way.

I suspect somewhere within [helper fetchUserSpreadsheetFeed] you are using some form of NSURLConnection. If you are using an asynchronous http request (where you setup the delegate for callback functions and such) the thread may terminate before the connection has a chance to invoke those callback functions and silently fail. Here's my solution which keeps the thread alive until the callbacks set a 'finished' variable to YES. (I also seem to have trouble posting code in these text boxes so if those angels that run around editing stuff can help me out that'd be great!)

- (void)fetchFeed {
//NSLog(@"making request");
[WLUtilities makeHttpRequest:self.feedUrlString withHttpHeaders:nil withDelegate:self];

//block this thread so it's still alive when the delegates get called
while(!finished) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

}

The problem I have with this solution is that spinning while loops are generally not good practice. I'm not sure as to the nature of the runloop business though, it may be properly sleeping and stuff but I'm not sure.

At any rate, you could give that a try and see what happens!

NOTE: my "WLUtilities" function is just a wrapper around the NSURLConnection function to create an asynchronous http request. Another solution you might try is simply using a synchronus request but I don't like this solution much either because the asynchronous call offers finer grained control over the connection.

Tom
Tom, you're correct. The GData ObjC Client uses callback selectors asynchronously. the fetchSpreadsheetFeed method never gets to its callback function. I'm going to give your solution a try. Thanks for the heads up
JustinXXVII