异步NSURLConnection,并发NSOperation,什么时候使用NSRunLoop?
我正在尝试在辅助线程中运行 NSURLConnection 异步(目标是 iOS4),为此我创建了一个并发 NSOperation,我想我已经快到了,但不清楚以下内容:
1)在 iOS4 NSOperationQueue addOperation 开始在新线程中进行操作,由于使用了GCD,基于技术问答 QA1712,但是,我的测试(模拟器和 iPad)显示 start() 总是在主线程上调用,任何想法,我是否需要在这里检查:如果在主线程然后产生一个新的?
2)如果 start 实际上是通过 addOperation() 在辅助线程上调用的,那么我可以通过在当前 NSRunLoop 上进行调度来启动我的异步 NSURLConnection:
[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.connection start];
就像 LinkedImageFetcher 示例 此处< /a> 并且我不需要循环直到完成:
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() 中,我确实需要运行当前线程runloop:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);
这是我设法在并发 NSOperation 中运行 NSURLConnection 的唯一实例,但我不确定是否需要运行 RunLoop,如果线程是由 GCD 提供的,如技术说明所述,我可以吗遵循2)中的逻辑或者我仍然需要运行线程的运行循环?如何测试 GCD 提供的线程?
非常感谢您的任何解释
I'm trying to run NSURLConnection async in a secondary thread (target is iOS4), for this I have created a concurrent NSOperation, I think I'm almost there, but am not clear on the following:
1) in iOS4 NSOperationQueue addOperation starts the operation in a new thread, because of the use of GCD, based on Technical Q&A QA1712, however, my tests (simulator and iPad) show that start() is always called on the main thread, any idea, do I need a check here: if on main thread then spawn a new one?
2) if start was actually called on a secondary thread by addOperation(), then I could start my async NSURLConnection by scheduling on the current NSRunLoop:
[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.connection start];
like the LinkedImageFetcher example here and I would not need to loop until completed with:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);
3) assuming my custom NSOperation start() is called on the main thread and 2) is correct, and I spawn a new thread in start() to call my custom main() method with:
[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];
In my main() I then do need to run the current thread run loop:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);
This is the only instance I've managed to run NSURLConnection in a concurrent NSOperation, but I'm not sure I do need to run the RunLoop, if the thread was supplied by the GCD as the tech notes state, could I follow the logic in 2) or would I still have to run the thread's runloop? How can I test a thread supplied by GCD?
Many thanks for any elucidation
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我最终解决了这个问题,所以认为人们可能对细节感兴趣:
1)在主线程上调用了 start() ,因为我使用的是 [NSOperationQueue mainQueue] 而不是使用 [[NSOperationQueue allc] init] 创建一个新队列。然而,在 NSOperation start() 中检查当前线程是否是 mainThread,然后直接从那里调用 main() 或通过生成一个新线程(如果我们在 mainThread 上)并没有什么坏处。
2)我意识到 LinkedImageFetcher 对于理解运行循环和线程来说太复杂了,而且没有必要如此,因为主题并不那么复杂。 start() 方法中所需要做的就是保持辅助线程运行循环继续运行,直到我们完成 (isCompleted),NSURLConnection 的所有运行循环都是监听来自连接的输入并触发回调 (didreceivereponse,是否收到数据等)。
3)是的,运行运行循环对于在同一线程(在本例中为辅助线程)上获取连接回调是必要的。
有关更多信息,请参阅 运行循环。
Well, I eventually worked this out so thought people might be interested in the details:
1) start() was called on the main thread because I was using [NSOperationQueue mainQueue] rather than creating a new queue with [[NSOperationQueue allc] init]. However a check in NSOperation start() for whether the current thread was the mainThread or not and then calling main() directly from there or by spawning a new thread (in case we were on the mainThread) did not hurt.
2) I realized that LinkedImageFetcher is far too complex for an understanding of run loops and threads, and unnecessarily so, because the topic is not that complicated. All that is needed within the start() method is to keep the secondary thread run loop going until we're done (isCompleted), all the run loop does for a NSURLConnection is listening to the inputs from the connection and firing callbacks (didreceivereponse, didreceivedata, etc.).
3) yes running the run loop is necessary to get connection callbacks on that same (secondary in this case) thread.
For more see Run Loops in Threading Programming Guide.
我不确定您想要实现什么: NSURLConnection API 有一个内置的异步方法 initWithRequest:delegate:
是否有任何具体原因不能使用它?
I'm not sure to understand what you're trying to achieve : NSURLConnection API has a built-in async method initWithRequest:delegate:
Is there any specific reason why you can't use this ?