(XCTestCase) 如何断言块是否已在主线程或外部(任何其他线程)调用?

(XCTestCase) How to assert if a block has been called in the main thread or outside(any other thread)?

如何断言一个块是否在主线程或外部(任何其他线程)被调用?假设我们有一个 class:

class A {
    func asyncOperation(handler: Void -> Void) {
        //some processing
        dispatch_async(dispatch_get_main_queue(), completionHandler)
    }
}

class ATests: XCTestCase {
    func testHandlerInMainThread(){
        let a = A()
        let expectation = expectationWithDescription("Handler must be called in main thread")

        a.asyncOperation{
            // how to get current_queue ? 
            XCTAssertEqual( current_queue, dispatch_get_main_queue())
            expectation.fulfill()
        }
        waitForExpectationsWithTimeout(3, handler: nil)
}

如果当前线程是主线程,您可以使用 NSThread 的 class 方法 isMainThread 其中 returns true

如果你想测试一个特定的队列是否真的是你的代码执行的队列,你可以测试队列的 "label":

 dispatch_queue_t
 dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

 const char *
 dispatch_queue_get_label(dispatch_queue_t queue);

后者在单元测试中更有用,而不是用于实际代码。您不应该使用这种方法来确定您的代码是否可能死锁,因为这是不够的!

编辑:

为了获取当前队列的标签(在Swift):

let label : String? = String.fromCString(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL))

使用dispatchPrecondition(condition:).

dispatchPrecondition(condition: .onQueue(self.myQueue))

来源:https://developer.apple.com/documentation/dispatch/1780605-dispatchprecondition