4

我正在尝试在辅助线程中运行 NSURLConnection 异步(目标是 iOS4),为此我创建了一个并发 NSOperation,我想我快到了,但不清楚以下内容:

1) 在 iOS4 NSOperationQueue addOperation 在新线程中开始操作,因为使用 GCD,基于Technical Q&A QA1712但是,我的测试(模拟器和 iPad)显示 start() 总是在主线程上调用,任何想法,我需要在这里检查一下:如果在主线程上然后产生一个新线程?

2) 如果 start 实际上是通过 addOperation() 在辅助线程上调用的,那么我可以通过在当前 NSRunLoop 上调度来启动我的异步 NSURLConnection:

[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.connection start];

就像这里的 LinkedImageFetcher 示例一样,在完成之前我不需要循环:

do {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);

3) 假设在主线程上调用了我的自定义 NSOperation start() 并且 2) 是正确的,并且我在 start() 中生成了一个新线程来调用我的自定义 main() 方法:

[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];

在我的 main() 中,我确实需要运行当前线程运行循环:

do {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);

这是我设法在并发 NSOperation 中运行 NSURLConnection 的唯一实例,但我不确定我是否需要运行 RunLoop,如果 GCD 作为技术说明状态提供线程,我可以按照逻辑在 2) 中还是我仍然需要运行线程的 runloop?如何测试 GCD 提供的线程?

非常感谢您的任何说明

4

2 回答 2

9

好吧,我最终解决了这个问题,所以认为人们可能会对细节感兴趣:

1) 在主线程上调用了 start(),因为我使用的是 [NSOperationQueue mainQueue] 而不是使用 [[NSOperationQueue allc] init] 创建一个新队列。然而,在 NSOperation start() 中检查当前线程是否是 mainThread,然后直接从那里调用 main() 或通过产生一个新线程(如果我们在 mainThread 上)并没有受到伤害。

2)我意识到 LinkedImageFetcher 对于理解运行循环和线程来说太复杂了,而且没有必要,因为这个主题并不复杂。start() 方法中需要做的就是保持辅助线程运行循环直到我们完成(isCompleted),所有运行循环对 NSURLConnection 所做的就是监听来自连接的输入并触发回调(didreceivereponse, didreceivedata 等)。

3)是的,运行运行循环对于在同一个(在这种情况下为辅助)线程上获取连接回调是必要的。

有关更多信息,请参阅线程编程指南中的运行循环

于 2011-06-04T18:59:01.890 回答
0

我不确定你想要达到什么目的:NSURLConnection API 有一个内置的异步方法 initWithRequest:delegate:

有什么具体原因不能使用它吗?

于 2011-04-30T13:01:50.660 回答