Lor*_*o B 5 asynchronous objective-c nsurlconnection nsoperation nsoperationqueue
是的我知道.关于这个NSOperation世界有很多问题和答案,但我仍然有一些疑问.我试图用两部分问题来解释我的怀疑.他们彼此相关.
在SO后nsoperationqueue和并发-VS-非并发,达伦写道:
"并发"操作本身是并发的; 它不需要NSOperationQueue为它创建一个线程.
但是稍微搜索一下,我发现a NSOperation,即使它被声明为并发(通过覆盖isConcurrent它返回的方法YES),也可以添加到NSOperationQueue.这是什么意思?如果我将一个并发NSOperation队列添加到队列中,那么幕后发生了什么?相反,如果我按原样使用并发操作(不将其添加到队列中)会发生什么?
从Apple doc获取的说明很清楚:
...操作队列忽略isConcurrent返回的值,并始终从单独的线程调用操作的start方法....通常,如果您始终使用具有操作队列的操作,则没有理由使它们并发.
然后,我真的对使用异步模式感兴趣NSOperation.我找到了Dave Dribin的一个很好的教程(并发操作).我得到了他的帖子的整体意义.
您无法使用异步模式(例如,使用异步NSURLConnection请求),因为无法调用委托.当main完成该操作将被删除.解决方案是覆盖start控制操作生命周期的方法......处理运行循环可能会很痛苦.
现在,试图理解他的帖子,我的疑问是需要start在主线程中运行该方法.
- (void)start
{
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
return;
}
// other code here...
}
Run Code Online (Sandbox Code Playgroud)
在处理异步API时,我们可以在启动时在主线程上开始异步调用,并使操作保持运行直到完成.
你能解释一下为什么吗?
先感谢您.
Ken*_*ses 11
在我看来,这个isConcurrent属性NSOperation令人困惑.它的确意味着"异步".也就是说,当它-start被调用时,无论操作是否已经完成(异步),它是否会快速返回?或者直到操作完成(同步)才返回?
正如Apple的文档所述,当一个操作排队到一个时,这并不重要NSOperationQueue,因为队列在工作线程上调用它,无论如何.如果它是同步的,那么该工作线程将专门用于该操作,直到它完成.如果它是异步的,那么-start将在操作完成之前返回,并且工作线程可以继续进行其他工作.
问题是,异步-start方法如何确保操作的工作继续进行?这可能需要产生一个单独的线程来完成工作,但这很愚蠢.最好让我们NSOperationQueue处理线程.
更有可能的是,它使用由外部事件驱动的运行循环源.NSURLConnection在它的异步模式中是那样的事情.但是,在这种情况下,它必须确保它调度运行循环源的线程a)将继续存在,并且b)将运行其运行循环.NSOperationQueue不能依赖工作线程做任何一件事.
同样,你可以为每个这样的操作创建自己的线程,特别是坚持并运行它的运行循环,但这是不必要的,并且再次提供的优势不是让操作同步并排队.
你已经知道的一个线程将坚持并运行其运行循环是主线程.因此,通常最好在主线程的运行循环上安排运行循环源.唯一需要注意的是,为了响应触发运行循环源处理程序的外部事件,您不会在主线程上执行任何长时间运行的工作.因此,例如,当NSURLConnection使用接收到的数据调用您的委托方法时,您不会对该数据进行昂贵的计算 - 或者,如果必须,则将该昂贵的计算移动到另一个线程.
另一种可能性,即中间立场,就是创建自己的一个线程作为许多异步操作的工作者.因此,不是使用主线程或每个操作的线程,而是使用单个线程,其工作只是停留在其运行循环中.所有异步操作都会在该线程的运行循环上安排自己.但是,这种方法并不是非常需要或有其优势.