NSOperation,start vs main

时间:2016-07-23 20:35:35

标签: nsoperation nsoperationqueue

根据Apple关于NSOperation的文档,我们必须覆盖非并发操作的main方法和并发操作的start方法。但为什么呢?

2 个答案:

答案 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)

我认为并发与非并发不仅仅是一个标志,而是一个非常重要的区别。通过使用两种不同的方法,可以确保您不使用并发操作,您应该使用非并发操作,反之亦然。

如果你弄错了,你的代码绝对不会因为这个设计而起作用。这就是你想要的,因为你立即修复它。如果只有一个方法,那么使用并发而不是非并发将导致非常微妙的错误,可能很难找到。非并发而不是并发将导致您也可能错过的性能问题。