苹果公司的文档显示,运营是同步运行的。那么,为什么在将操作添加到队列后继续运行代码呢?
这是我的代码:
let op = BlockOperation(block: { print("Done") })
let qu = OperationQueue()
qu.addOperation(op)
print("after!")以下是调试结果:
之后! 完成
发布于 2022-07-09 19:14:58
你说过:
苹果公司的文档显示,运营是同步运行的。那么,为什么在将操作添加到队列后继续运行代码呢?
调试输出是正确的。BlockOperation将针对将其添加到操作队列的线程异步运行。Operation和OperationQueue文档使用的术语混淆和不一致无助于此(见下文)。
但是,简而言之,添加到操作队列中的操作将针对将它们添加到队列的线程异步运行(除非您明确地希望“等待到完成”,即为addOperations(_:waitUntilFinished:)的第二个参数提供addOperations(_:waitUntilFinished:);但这是一个反模式,我们并不经常使用它)。
我不知道这是否是混乱的根源,但也存在一个问题,即操作包装的任务本身是同步的还是异步的。Apple文档将这些操作分别称为“非并发”或“并发”操作。
BlockOperation只用于“非并发”任务(即,当块完成时,BlockOperation就完成了)。因此,如果您无意中看到任何提到BlockOperation的同步性质的文档,即引用提供给操作的块的同步(即非并发)性质,而不是BlockOperation与将其添加到队列的线程之间更广泛的关系。对于将它们添加到队列的线程(无论操作本身是否并发),操作都异步运行。
FWIW,如果您确实是在将一个固有的异步任务(例如网络请求)包装在一个操作中,那么在Apple的术语中称为“并发”操作。您不会将BlockOperation用于“并发”操作。您将子类Operation,为“并发”操作执行必要的KVO。(如果你真的想翻到兔子洞里去,请看https://stackoverflow.com/a/40560463/1271826或https://stackoverflow.com/a/48104095/1271826,但这与眼前的问题很大程度上无关。)
在Operation和OperationQueue文档中有最后一个“同步”和“异步”的概念。具体来说,文档驻留在start方法上下文中的“异步”和“同步”操作,即没有添加到队列中但刚刚开始的操作。如果您在“同步操作”上调用start (而不是将其添加到队列中),则调用线程将等待。如果您将start称为“异步操作”,则调用线程不会等待。
我甚至不想提这个特殊的术语,但我只提到那些在苹果文档中的绊脚石。苹果在这个部分中使用的“同步”和“异步”只适用于start方法的上下文。显然,我们(和苹果,在他们自己的文档中的其他地方)经常使用这些术语更普遍。
你提出了另一个问题:
同步代码立即运行,调用它的线程等待同步代码完成。或者只有在同步代码在同一个线程上运行时才会这样做?
“同步”只是指调用者在同步代码完成之前不会继续。
不是分割头发,但它不能保证同步代码将立即执行(虽然它一般会)。这只意味着调用者在同步调用结束之前不会继续。但是,例如,如果将同步分派的代码添加到一个积压的队列中,它可能不会立即启动。
术语“同步”也不能保证它将运行在同一个线程或另一个线程上。有时is会在当前线程上运行它。有时,它只是在当前线程上等待,而同步任务在其他线程上完成。这取决于具体情况。
“同步”只意味着调用方将等待,而不确定同步代码将在何时或何处执行。就这样。
https://stackoverflow.com/questions/72892185
复制相似问题