Contents

前文

这个是关于同步执行和异步执行的策略方法。

void grey_execute_sync(void (^block)()) {
    if ([NSThread isMainThread]) {
        NSLog(@"grey_execute_sync() cannot be invoked on the main thread. Aborting.");
        abort();
    }

    dispatch_semaphore_t waitForBlock = dispatch_semaphore_create(0);
    CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{
        block();
        dispatch_semaphore_signal(waitForBlock);
    });
    // CFRunLoopPerformBlock does not wake up the main queue.
    CFRunLoopWakeUp(CFRunLoopGetMain());
    // Waits until block is executed and semaphore is signalled.
    dispatch_semaphore_wait(waitForBlock, DISPATCH_TIME_FOREVER);
}

void grey_execute_async(void (^block)()) {
    CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, block);
    // CFRunLoopPerformBlock does not wake up the main queue.
    CFRunLoopWakeUp(CFRunLoopGetMain());
}

这里使用了一个不常用的 API,CFRunLoopPerformBlock。

这个函数可以指定 block 运行在特定的 runloop mode 下,对比 GCD 的函数,可能好处就在这里吧。

This method enqueues the block only and does not automatically wake up the specified run loop. Therefore, execution of the block occurs the next time the run loop wakes up to handle another input source. If you want the work performed right away, you must explicitly wake up that thread using the CFRunLoopWakeUp function.

并且需要使用 CFRunLoopWakeUp 把 runloop 唤醒。

某种奇巧淫技吧。

Contents