2017-10-18 41 views
0

使用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]; 
    }); 
} 
+0

在斯威夫特你会经常使用'dispatchPrecondition(条件:.onQueue (。主要))'。在Objective-C中,基于['[NSThread isMainThread]'](https://developer.apple.com/documentation/foundation/nsthread/1408455-mainmainread)',你很可能会坚持'NSAssert'或'NSLog'。 – Rob

回答

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中看到堆栈并追溯到调用源。

它运行时就像在主线程检查器苹果(我是不是能够得到静态分析仪显示警告。只有当我跑的代码,主线程检查器会暂停该应用程序,并在主线程上显示错误)。

唯一的问题是,我无法找到一个方法来“标记”功能,因为只有主线程..但是这是近..

+0

是的,我已经到了用'NSAssert(NSThread.isMainThread,...);'开始我的很多方法的地步。但其中很大一部分几乎和我发布的一样简单,应该很容易找到。 :) –

相关问题