NSURLConnection委托和线程 - iPhone

时间:2009-08-01 10:13:57

标签: iphone cocoa cocoa-touch multithreading nsurlconnection

我有一个类通过NSURLConnection更新app文档目录中的两个.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 个答案:

答案 0 :(得分:8)

我发现了一些有趣的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 :(得分:4)

目前在您提供的代码中,getNewDatabase:正在您的应用程序的主线程上运行。在这种特殊情况下的问题不仅仅是线程的生命周期,正如James在他的案例中所观察到的那样。

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

Dave Dribin在NSOperation内部使用异步API(例如NSURLConnection)excellent article。或者,只要您在后台线程中运行,您也可以简化流程并在NSOperation中使用同步API方法,例如initWithContentsOfURL:

Marcus Zarra也written a tutorial证明了将NSOperationQueue合并到简单的后台操作是多么容易。