NSURLConnection delegation and streams - iPhone

I have a class that updates two .plist files in the application document directory through NSURLConnection. The class acts as its own delegate for NSURLConnection. It works correctly when I request one file, but fails when I try to update two files. Does it seem like I should start a new thread for each of the getNewDatabase messages?

- (void)getAllNewDatabases { [self performSelectorOnMainThread:@selector(getNewDatabase:) withObject:@"file1" waitUntilDone:YES]; [self performSelectorOnMainThread:@selector(getNewDatabase:) withObject:@"file2" waitUntilDone:YES]; } - (BOOL)getNewDatabase:(NSString *)dbName { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSMutableString *apiString = [[NSMutableString alloc] initWithString:kAPIHost]; [apiString appendFormat:@"/%@.plist",dbName]; NSURLRequest *myRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:apiString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSURLConnection *myConnection = [[NSURLConnection alloc] initWithRequest:myRequest delegate:self]; [apiString release]; if( myConnection ) { //omitted for clarity here } [pool release]; } //NSURLConnection delegate methods here ... 
+3
source share
2 answers

I found something interesting in NSURLConnection and NSThread - the thread will only work as long as it executes the method that you call from it.

In the above case, the thread will only work until getNewDatabase:(NSString *)dbName accepts termination, so it kills any of its delegation methods before they really have time to do anything.

I found this site that gives a better explanation and solution to the problem.

I changed it a bit so that I had a user timeout if it did not end in a certain period of time (it is convenient when someone walks between access points)

  start = [NSDate dateWithTimeIntervalSinceNow:3]; while(!isFinished && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]){ if([start compare:[NSDate date]] == NSOrderedAscending){ isFinished = YES; } } 
+8
source

At the moment, in the code you specified, getNewDatabase: running in the main thread of your application. The problem in this particular case is then something other than the life cycle of the thread, as James noted in his case.

If you intended to perform this operation in the background, I would recommend using NSOperationQueue and NSOperation instead of solving the problem with the current code. I think your case is great for NSOperationQueue , especially if you have several loading tasks.

Dave Dribin has an excellent article on using an asynchronous API, such as NSURLConnection, inside NSOperation . Alternatively, if you are working in a background thread, you can also simplify this process and simply use the synchronous API method instead of your NSOperation, for example initWithContentsOfURL:

Marcus Zarra also wrote a tutorial that demonstrates how easy it is to enable and use NSOperationQueue for simple background operations.

+4
source

All Articles