简体   繁体   English

为什么我的 BlockOperation 在我添加到 OperationQueue 后会继续?

[英]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). OperationOperationQueue文档使用的混乱和不一致的术语无济于事(见下文)。

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/1271826https://stackoverflow.com/a/48104095/1271826 ,但这在很大程度上与问题无关在眼前。)


There is a final notion of “synchronous” vs “asynchronous” within the Operation and OperationQueue documentation. OperationOperationQueue文档中有一个“同步”与“异步”的最终概念。 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.

相关问题 为什么定时器在失效后继续执行? - Why does timer continue to execute after invalidation? ios8自定义键盘:为什么当我添加UIImages时,它不能在设备上运行? - ios8 Custom Keyboard: Why when I add UIImages does it not run on my device? 为什么每次将IBactioning添加到类中时,我的应用程序都会崩溃 - Why does my App keeps crashing every time I add the IBactioning into a class Swift:将操作添加到 DispatchQueue/OperationQueue 但稍后启动队列 - Swift: Add operations to DispatchQueue/OperationQueue but launch the queue later 如何确保OperationQueue中的操作一个接一个地完成 - How to assure that operations in an OperationQueue are finished one after another 为什么我的UIButton在发生问题后仍然保留? - Why does my UIButton remain after a segue? 如果我调用cancelAllOpeartions,OperationQueue不会从队列中删除操作 - OperationQueue is not removing the operations from queue if I call cancelAllOpeartions start() 用于主线程上的 BlockOperation - start() for BlockOperation on the main thread 在AVAudioPlayer暂停后,歌曲不会继续在Swift上播放 - In AVAudioPlayer after a pause the song does not continue on Swift 为什么我以编程方式添加的UIView没有连接到UIViewController? - Why is my UIView that I add programmatically not connected to my UIViewController?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM