并发NSOperation,为什么要开始主线程?

时间:2013-01-13 21:28:27

标签: ios objective-c cocoa-touch

我正在研究这个源代码,它演示了如何在NSOperation中使用NSURLConnection: link

我对第76

的代码感到困惑
if (![NSThread isMainThread])
    {
        [self performSelectorOnMainThread:@selector(start)
                               withObject:nil waitUntilDone:NO];
        return;
    }

为什么作者确保代码在主线程上运行?

NSOperation的重点不是不在主线程和后台线程上运行,以至于它不会阻塞吗?

代码来自本文解释它,虽然它没有回答我的问题:http://eng.pulse.me/concurrent-downloads-using-nsoperationqueues/

5 个答案:

答案 0 :(得分:1)

NSURLConnection docs,你可以看到;

  

NSURLConnection的委托方法 - 由NSURLConnectionDelegate协议协议定义 - 允许对象接收有关URL请求的异步加载的信息回调。 [...] 在启动相关NSURLConnection对象的异步加载操作的线程上调用这些委托方法。

在NSURLConnection上启动操作适用于任何线程,但是如果您想要 - 例如 - 显示进度,则在GUI /主线程上获取委托回调非常有用。

答案 1 :(得分:0)

如果您使用NSURLConnection异步,则需要在主线程上启动此操作以获取回调。如果从后台线程启动异步NSURLConnection,如果你的后台线程启动你的NSURLConnection忙于其他活动,你可能会失去回调。

答案 2 :(得分:0)

如果在主线程中调用start方法,当前操作主方法将在主线程中运行,但是你将当前操作推送到NSOperationQueue(不是主队列),在子线程中启动方法调用,当前操作主方法在子线程。

Sub Thread Photo

Main Method in Sub Thread

答案 3 :(得分:-1)

如果这是一个例子,我相信这是为了让你看到那里的代码与之间的区别。如果这个代码同时执行并且应该让你的主线程保持活动,那么确实那段代码不应该存在,但它可能已被放在那里供你删除并查看差异。不过你确实是对的。浏览文件的其余部分,如果您想要保持主线程处于打开状态,则看起来不应该在那里。

答案 4 :(得分:-1)

原因是,在iOS 4.0+上,操作是并发与否,操作在后台线程中运行。由于在这种情况下操作是并发的,因此该方法立即存在并且线程被终止,因此没有调用委托方法(NSURLConnection在它开始的线程上调用委托方法)。

唯一的选择是,要么启动NSRunLoop(非常繁忙),要么使用已经有一个(主线程)的线程 - 这就是为什么start方法是从主线程运行的。

与许多建议的更新UI无关(虽然我理解这一点,但在队列中运行NSURLConnection的整个原因是在单独的线程中处理委托回调以避免阻止UI)。这不是作者的意图,它是UIKit安全的事实仅仅是后果。