NSURLConnection委托和线程 - iPhone

问题描述:

我有一个类,通过NSURLConnection更新应用程序文档目录中的两个.plist文件。该类充当它自己的NSURLConnection委托。当我要求单个文件时它工作正常,但当我尝试更新两个文件时失败。它看起来像我应该为每个getNewDatabase消息启动一个新的线程?NSURLConnection委托和线程 - iPhone

- (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 ... 

我发现了一些与NSURLConnection的和有趣的NSThread - 线程只会活,只要它需要执行您从中调用该方法。

在上面的例子中,线程的生存时间只有getNewDatabase:(NSString *)dbName需要完成的时间,因此在他们真正有时间去做任何事情之前,终止它的任何委托方法。

我发现this网站,提供更好的解释和问题

我调整了一点点,所以我可以有一个自定义的时间,如果它在给定的时间内未完成的解决方案(方便当有人走动的接入点之间)

start = [NSDate dateWithTimeIntervalSinceNow:3]; 

    while(!isFinished && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
                beforeDate:[NSDate distantFuture]]){ 

    if([start compare:[NSDate date]] == NSOrderedAscending){ 
     isFinished = YES; 
    } 
} 
+1

您链接到的博客文章已被移动 - 我相信这是它:http://www.sortedbits.com/nsurlconnection-in-its-own-thread – 2012-06-11 13:45:56

正如您所提供的代码目前维持,getNewDatabase:是应用程序的主线程上运行。正如詹姆斯在他的案例中所看到的那样,这个特殊情况下的问题不是线程的生命周期。

如果您确实打算在后台执行此操作,我建议您考虑使用NSOperationQueueNSOperation,而不是使用当前代码解决问题。我认为你的情况非常适合NSOperationQueue,尤其是考虑到你有多个下载任务需要执行。

Dave Dribin有一个excellent article关于在NSOperation内部使用异步API(例如NSURLConnection)。另外,只要你在后台线程中运行,你也可以简化这个过程,只需在NSOperation中使用同步API方法,比如initWithContentsOfURL:

Marcus Zarra还有written a tutorial,它演示了如何简单地将NSOperationQueue合并并用于简单的后台操作。

+0

谢谢 - 与此同时 - 我分叉了一个版本与NSOperation/NSOperationQueue完全一样。现在完美运作。 – FluffulousChimp 2009-08-01 15:21:26