NSURLConnection委托和线程 - iPhone

3

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

- (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 ...
2个回答

8
我在使用NSURLConnection和NSThread时发现了一件有趣的事情——线程的生命周期仅为从中调用的方法所需的时间。因此,它会在getNewDatabase:(NSString *)dbName执行完之后立即关闭其所有代理方法,导致它们没有实际执行任何操作就被终止。
我找到了这个网站,它提供了更好的解释和问题的解决方案。我稍微做了一些调整,以便在给定的时间范围内无法完成时具有自定义超时功能(当某人在访问点之间移动时非常方便)。
    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 - Martin Gjaldbaek

4
在你提供的代码中,getNewDatabase: 当前正在应用程序的主线程上运行。在这种情况下,问题不在于线程的生命周期,正如James在他的案例中观察到的那样。
如果你确实打算在后台执行此操作,我建议你研究一下使用NSOperationQueueNSOperation,而不是使用当前代码解决问题。我认为你的情况非常适合NSOperationQueue,特别是考虑到你有多个下载任务要执行。
Dave Dribin撰写了一篇关于在NSOperation内部使用异步API(例如NSURLConnection)的优秀文章。或者,只要你在后台线程中运行,你也可以简化流程,在你的NSOperation中使用同步API方法,例如initWithContentsOfURL:
Marcus Zarra还编写了一篇教程,演示了将NSOperationQueue用于简单后台操作的易用性。

谢谢 - 与此同时 - 我分叉了一个使用NSOperation / NSOperationQueue实现这一点的版本。现在完美运行。 - FluffulousChimp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接