【发布时间】:2020-02-19 13:58:37
【问题描述】:
为什么在主线程上调用具有超过 1 个块的 BlockOperation 的 start() 而不在主线程上调用其块? 我的第一个测试总是通过但不是每次都通过 - 有时块不在主线程上执行
func test_callStartOnMainThread_executeOneBlockOnMainThread() {
let blockOper = BlockOperation {
XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
}
blockOper.start()
}
func test_callStartOnMainThread_executeTwoBlockOnMainThread() {
let blockOper = BlockOperation {
XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
}
blockOper.addExecutionBlock {
XCTAssertTrue(Thread.isMainThread, "Expect second block was executed on Main Thread")
}
blockOper.start()
}
即使下一个代码也失败了
func test_callStartOnMainThread_executeTwoBlockOnMainThread() {
let asyncExpectation = expectation(description: "Async block executed")
asyncExpectation.expectedFulfillmentCount = 2
let blockOper = BlockOperation {
XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
asyncExpectation.fulfill()
}
blockOper.addExecutionBlock {
XCTAssertTrue(Thread.isMainThread, "Expect second block was executed on Main Thread")
asyncExpectation.fulfill()
}
OperationQueue.main.addOperation(blockOper)
wait(for: [asyncExpectation], timeout: 2.0)
}
【问题讨论】:
-
为什么你认为
BlockOperation将始终且仅在主线程上执行?检查文档:添加到块操作的块以默认优先级分派到适当的工作队列。块本身不应对其执行环境的配置做出任何假设。 -
但是如果我希望我的任务只在主线程上执行呢? (我知道这可能会很奇怪)如果我调用 OperationQueue.main.addOperation(blockOper) - 我没有得到期望。块是否在主线程上执行 - 这取决于我不知道的事情
-
如果你使用
OperationQueue.main.addOperation(blockOper)而不是blockOper.start(),这确实应该在主线程中执行。但这不是您的代码中显示的内容,还是我有什么问题? -
@AndreasOetjen - 不,即使那样,
addExecutionBlock模式仍然可以体现 OP 描述的行为。正如 Andreas 所引用的,在使用addExecutionBlock时,不要对执行环境做出任何假设。 -
@Rob 嗯,文档中似乎有点矛盾,我猜:据我了解,不要假设有关执行环境的任何内容仅与
BlockOperation本身,因为它不知道它将被排入哪个OperationQueue。使用OperationQueue.main时,操作应始终在主线程中执行。至少这是我对 在应用程序的主线程上一次执行一个操作 的理解(但是 BlockOperation 文档声明 Blocks added ... 以默认优先级分派到适当的工作队列。 )
标签: swift blockoperation