【问题标题】:NSURLConnection delegation and threading - iPhoneNSURLConnection 委托和线程 - iPhone
【发布时间】:2009-08-01 10:13:57
【问题描述】:

我有一个类通过 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 ...

【问题讨论】:

    标签: iphone cocoa cocoa-touch multithreading nsurlconnection


    【解决方案1】:

    我在 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;
        }
    }
    

    【讨论】:

    【解决方案2】:

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

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

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

    Marcus Zarra 也有 written a tutorial,它演示了合并和使用 NSOperationQueue 进行简单的后台操作是多么容易。

    【讨论】:

    • 谢谢 - 同时 - 我派生了一个与 NSOperation / NSOperationQueue 完全一样的版本。现在完美运行。
    猜你喜欢
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多