[英]Why does my BlockOperation continue after I add it to an OperationQueue?
Apple documentation says that Operations run synchronously.苹果文档说操作是同步运行的。 Why then does the code continue to run after an operation is added to a queue?那么为什么在将操作添加到队列后代码继续运行呢?
Here is my code:这是我的代码:
let op = BlockOperation(block: { print("Done") })
let qu = OperationQueue()
qu.addOperation(op)
print("after!")
Here is the debug results:这是调试结果:
after!后!
Done完毕
You said:你说:
Apple documentation says that Operations run synchronously.苹果文档说操作是同步运行的。 Why then does the code continue to run after an operation is added to a queue?那么为什么在将操作添加到队列后代码继续运行呢?
Your debug output is correct.您的调试输出是正确的。 The BlockOperation
will run asynchronously with respect to the thread which added it to the operation queue. BlockOperation
将相对于将其添加到操作队列的线程异步运行。 The confusing and inconsistent terminology employed by the Operation
and OperationQueue
documentation does not help the matter (see below). Operation
和OperationQueue
文档使用的混乱和不一致的术语无济于事(见下文)。
But, in short, operations added to an operation queue will run asynchronously with respect to the thread which added them to the queue (unless you explicitly wanted to “wait until finished”, ie, you supply true
for the second parameter of addOperations(_:waitUntilFinished:)
; but that is an anti-pattern which we simply do not use very often).但是,简而言之,添加到操作队列的操作将相对于将它们添加到队列的线程异步运行(除非您明确想要“等到完成”,即,您为true
addOperations(_:waitUntilFinished:)
; 但这是一种反模式,我们根本不经常使用)。
I do not know if this is the source of the confusion or not, but there is also a question as to whether the task wrapped by the operation is, itself, synchronous or asynchronous.我不知道这是否是混乱的根源,但还有一个问题是操作包装的任务本身是同步的还是异步的。 The Apple documentation refers to these as “non-concurrent” or “concurrent” operations, respectively. Apple 文档将这些分别称为“非并发”或“并发”操作。
BlockOperation
is for “non-concurrent” tasks only (ie, when the block finishes, the BlockOperation
is finished). BlockOperation
仅用于“非并发”任务(即,当块完成时, BlockOperation
完成)。 So, if you stumble across any documentation that refers to the synchronous nature of BlockOperation
, that is in reference to the synchronous, ie, non-concurrent, nature of the block supplied to the operation, not the broader relationship between the BlockOperation
and the thread that added it to the queue.因此,如果您偶然发现任何涉及BlockOperation
同步性质的文档,即涉及提供给操作的块的同步(即非并发)性质,而不是BlockOperation
和线程之间更广泛的关系将其添加到队列中。 Operations run asynchronously with respect to the thread that added them to the queue (whether the operation, itself, is concurrent or not).操作相对于将它们添加到队列中的线程异步运行(无论操作本身是否并发)。
FWIW, if you really were wrapping an inherently asynchronous task (such as a network request) within an operation, that called a “concurrent” operation in Apple's terminology. FWIW,如果你真的在一个操作中包装了一个固有的异步任务(例如网络请求),这在 Apple 的术语中称为“并发”操作。 You would not use BlockOperation
for a “concurrent” operation.您不会将BlockOperation
用于“并发”操作。 You would subclass Operation
, perform the necessary KVO for “concurrent” operations.您将继承Operation
,为“并发”操作执行必要的 KVO。 (If you really want to go tumbling down that rabbit hole, see https://stackoverflow.com/a/40560463/1271826 or https://stackoverflow.com/a/48104095/1271826 , but this is largely unrelated to the question at hand.) (如果你真的想从那个兔子洞里翻滚,请参阅https://stackoverflow.com/a/40560463/1271826或https://stackoverflow.com/a/48104095/1271826 ,但这在很大程度上与问题无关在眼前。)
There is a final notion of “synchronous” vs “asynchronous” within the Operation
and OperationQueue
documentation. Operation
和OperationQueue
文档中有一个“同步”与“异步”的最终概念。 Specifically, the documentation dwells on the terms “asynchronous” and “synchronous” operations in the context of the start
method, ie, operations that are not added to a queue, but are just started immediately.具体来说, 文档详细介绍了start
方法上下文中的术语“异步”和“同步”操作,即未添加到队列中但立即启动的操作。 If you call start
on a “synchronous operation” (rather than adding it to a queue), the calling thread will wait.如果您在“同步操作”上调用start
(而不是将其添加到队列中),则调用线程将等待。 If you call start
an “asynchronous operation”, the calling thread will not wait.如果你调用start
一个“异步操作”,调用线程将不会等待。
I hate to even bring up this idiosyncratic terminology, but only mention for those stumbling through Apple's documentation.我什至讨厌提出这个特殊的术语,但只提及那些在 Apple 文档中磕磕绊绊的人。 Apple's use of “synchronous” vs “asynchronous” in this section only applies within the context of the start
method. Apple 在本节中对“同步”与“异步”的使用仅适用于start
方法的上下文。 Obviously, we (and Apple, elsewhere in their own documentation) often use these terms more generally.显然,我们(和 Apple,在他们自己的文档中的其他地方)经常更普遍地使用这些术语。
You raised another question:你提出了另一个问题:
The synchronous code runs immediately and the thread that calls it waits until the synchronous code finishes.同步代码立即运行,调用它的线程等待同步代码完成。 Or is that only if the synchronous code runs on the same thread?或者只有当同步代码在同一个线程上运行时?
“Synchronous” simply means that the caller will not proceed until the synchronous code finishes. “同步”仅仅意味着调用者在同步代码完成之前不会继续。
Not to split hairs, but it makes no assurances that the synchronous code will execute immediately (though it generally will).不要分心,但它不能保证同步代码会立即执行(尽管通常会)。 It just means that the caller will not proceed until the synchronous call finishes.这只是意味着调用者在同步调用完成之前不会继续。 But if, for example, the synchronously dispatched code is added to a queue that is backlogged, it might not start immediately.但是,例如,如果将同步分派的代码添加到积压的队列中,它可能不会立即启动。
The term “synchronous” also makes no assurances that it will run on the same thread or a different one.术语“同步”也不保证它将在同一线程或不同线程上运行。 Sometimes is will run it on the current thread.有时会在当前线程上运行它。 Sometimes it will simply wait on the current thread while the synchronous task finishes on some other thread.有时它只会在当前线程上等待,而同步任务在其他线程上完成。 It depends upon the particular situation.这取决于具体情况。
“Synchronous” only means that the caller will wait, with no assurances about when or where the synchronous code will execute. “同步”仅表示调用者将等待,不保证同步代码将在何时何地执行。 That's it.而已。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.