将方法标记为主线程?

时间:2017-10-18 23:14:00

标签: ios multithreading clang-static-analyzer

使用Xcode 9,如果编译器能够确定您是从后台线程调用UIKit,则可以获得分析器警告。

有没有办法让我自己的方法获得这些?

例如:

@interface MyObject

- (void)doThingOnMainThread NS_MAIN_THREAD_ONLY;
// where NS_MAIN_THREAD_ONLY is a thing I just made up, as far as I know

@end

其他地方:

- (void)otherMethod {
    MyObject *myObject = [MyObject sharedObject];
    dispatch_queue_t queue =
        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        // I'd like a warning here, if possible!
        [myObject doThingOnMainThread];
    });
}

1 个答案:

答案 0 :(得分:1)

我能得到的最接近的是:

#ifdef DEBUG
    #if TARGET_OS_SIMULATOR
        #define ENSURE_MAIN_THREAD if (![NSThread isMainThread]) { \
            printf("ERROR: UI USAGE ON BACKGROUND THREAD\n"); \
            __asm__ volatile("int3"); \
        }
    #else
        #define ENSURE_MAIN_THREAD if (![NSThread isMainThread]) { \
            printf("ERROR: UI USAGE ON BACKGROUND THREAD\n"); \
            __builtin_debugtrap(); \
        }
    #endif
#endif

然后我用它像:

- (void)testFunc {
    ENSURE_MAIN_THREAD

    printf("HERE");
}

- (void)testRun {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self testFunc];
    });
}

在后台线程上运行时,它会创建一个断点或陷阱,以便您可以在XCode中查看堆栈并追溯到调用源。

它就像Apple的Main-Thread-Checker一样运行时(我无法让静态分析器显示警告..只有当我运行代码时,Main-Thread-Checker会暂停应用程序,并在主线程上显示错误)。

唯一的问题是我找不到一种方法将一个函数“标记”为主线程..但这很接近..