根据Apple关于NSOperation的文档,我们必须覆盖非并发操作的main
方法和并发操作的start
方法。但为什么呢?
答案 0 :(得分:22)
首先,请记住"并发"和"非并发"在NSOperation
中有一些特殊的含义,往往会让人感到困惑(并且与#34;异步/同步"同义使用)。 "并行"意味着"操作将管理自己的并发和状态。" "非并发"意味着"操作需要其他东西,通常是队列,来管理它的并发性,并希望默认的状态处理。"
start
执行所有默认状态处理。部分原因是它设置isExecuting
,然后调用main
,当main
返回时,它会清除isExecuting
并设置isFinished
。由于您正在处理自己的状态,因此您不希望这样(您不想退出main
完成操作)。因此,您需要实施自己的start
而不是致电super
。现在,如果您愿意,您仍然可以使用main
方法,但由于您已经覆盖了start
(并且调用了main
),人们只需将所有代码放入start
。
作为一般规则,不要使用并发操作。它们很少是你的意思。他们绝对并不意味着"在后台运行的东西。"这两种操作都可以在后台运行( 都不能在后台运行)。问题是你是否想要默认的系统行为(非并发),或者你是否想要自己处理所有事情(并发)。
如果您自己处理它的想法是"启动NSThread
,"你几乎肯定做错了(除非你这样做是为了与需要它的C / C ++库接口)。如果它正在创建一个队列,你可能做错了(NSOperation有各种各样的功能来避免这种情况)。如果它几乎是任何看起来像是手动处理后台处理的东西,"你可能做错了。默认(非并发)行为几乎肯定比您要做的更好。
如果您正在使用的API已经为您处理并发,则并发操作可能会有所帮助。当main
返回时,非并发操作结束。那么如果你的操作包含像NSURLConnection
这样的异步事情呢?处理这种情况的一种方法是使用调度组,然后在dispatch_wait
的末尾调用main
,这样它就不会返回,直到完成所有操作。没关系。我一直这样做。但是它会阻止一个不会被阻止的线程,这会浪费一些资源,而在一些精心设计的角落案例中可能会导致死锁(真的精心设计。苹果声称它可能并且他们&已经看过了,但是我甚至没有能够让它在有目的的情况下发生。)
另一种方法是将自己定义为并发操作,并在isFinished
委托方法中手动设置NSURLConnection
。如果您正在包装其他异步接口(如Dispatch I / O),则会出现类似情况,并且并发操作可能会更有效。
(理论上,当您想要在不使用队列的情况下运行操作时,并发操作也很有用。我可以想象一些非常复杂的情况,这是有道理的,但它是一个延伸,如果您和#39;在那条船上,我假设你知道你正在做什么。)
但如果您有任何疑问,只需使用默认的非并发行为即可。你几乎总能以轻微的麻烦得到你想要的行为(特别是如果你使用派遣小组),然后你不必将你的大脑包裹在"并发&#34的有些令人困惑的解释中;在文档中。
答案 1 :(得分:0)
我认为并发与非并发不仅仅是一个标志,而是一个非常重要的区别。通过使用两种不同的方法,可以确保您不使用并发操作,您应该使用非并发操作,反之亦然。
如果你弄错了,你的代码绝对不会因为这个设计而起作用。这就是你想要的,因为你立即修复它。如果只有一个方法,那么使用并发而不是非并发将导致非常微妙的错误,可能很难找到。非并发而不是并发将导致您也可能错过的性能问题。