【问题标题】:Problems Getting Multiple NSURLConnections to Run in Parallel让多个 NSURLConnections 并行运行的问题
【发布时间】:2011-06-05 03:28:16
【问题描述】:

我正在尝试让多个 NSURLConnections 并行(同步)运行,但是如果它不在主线程上运行(代码块在下面注释掉),则 URL 连接似乎根本不起作用(无的 NSURLConnection 委托方法被触发)。这是我的代码(NSOperation 子类的实现文件):

- (void)start
{
    NSLog(@"DataRetriever.m start");
    if ([self.DRDelegate respondsToSelector:@selector(dataRetrieverBeganExecuting:)])
        [self.DRDelegate dataRetrieverBeganExecuting:identifier];

    if ([self isCancelled]) {
        [self finish];
    } else {

        /*
        //If this block is not commented out NSURLConnection works, but not otherwise
        if (![NSThread isMainThread])
        {
            [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
            return;
        }*/

        SJLog(@"operation for <%@> started.", _url);

        [self willChangeValueForKey:@"isExecuting"];
        _isExecuting = YES;
        [self didChangeValueForKey:@"isExecuting"];

        NSURLRequest * request = [NSURLRequest requestWithURL:_url];
        _connection = [[NSURLConnection alloc] initWithRequest:request
                                                      delegate:self];
        if (_connection == nil)
            [self finish];
    } //not cancelled


}//start

用调试器运行它,在这个 start 方法结束后,没有一个 NSURLConnection 委托触发(我在那里设置了断点)。但是在主线程上它工作得很好。有什么想法吗?谢谢!

【问题讨论】:

    标签: objective-c cocoa-touch ios4 nsurlconnection nsurlrequest


    【解决方案1】:

    后台线程不会自动有active run loop。您需要在创建 NSURLConnection 后启动运行循环,以便从中获取任何输入。幸运的是,这很简单:

    [[NSRunLoop currentRunLoop] run];
    

    当您说您正在同步运行连接时,您是不正确的。 NSURLConnection 的默认模式是异步的——它为您创建和管理一个新的后台线程,并回调原始线程上的委托。因此,您无需担心阻塞主线程。

    如果您确实想要执行同步连接,您可以使用sendSynchronousRequest:returningResponse:error:,它将直接返回数据。详情请见"Downloading Data Synchronously"

    【讨论】:

      【解决方案2】:

      NSURLConnection 需要一个活动的运行循环才能真正工作;确保这一点的最简单方法是从主线程运行它。

      注意 NSURLConnection 通常是异步运行的(如果你同步运行一个,它真正的作用是在另一个线程上异步运行一个然后阻塞直到完成),所以除了你在委托方法中做的任何处理之外它不应该不会对 UI 响应产生太大影响。

      【讨论】:

      • 难道不能让主线程启动它并让后台线程处理 NSURLConnection 委托方法吗?因为在我的应用程序中,它非常明显,因为我的视图中的其他项目在我的 NSURLConnections 完成之前不会加载(它们需要大量计算)。如果我可以采取一种困难的方法来实现这一点,或者类似的事情,我就是游戏。
      • 可以使用后台线程,如果您在其上运行运行循环。或者,您可以使用委托方法中的 performSelectorInBackground:withObject: 来启动密集型任务。
      猜你喜欢
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      • 1970-01-01
      • 2019-03-30
      • 1970-01-01
      相关资源
      最近更新 更多