Method Swizzlingを使い、-[UIView setNeedsDisplay] を置き換えてメインスレッド以外で呼び出されるケースを検出するという話。
(void)toggleViewMainQueueChecking
{
[UIView swizzleMethod:@selector(setNeedsLayout)
withMethod:@selector(_setNeedsLayout_MainQueueCheck)];
[UIView swizzleMethod:@selector(setNeedsDisplay)
withMethod:@selector(_setNeedsDisplay_MainQueueCheck)];
[UIView swizzleMethod:@selector(setNeedsDisplayInRect:)
withMethod:@selector(_setNeedsDisplayInRect_MainQueueCheck:)];
}そしてこんな感じで仕掛けておく
- (void)methodCalledNotFromMainQueue:(NSString *)methodName
{
NSLog(@"-[%@ %@] being called on background queue. Break on -[UIView methodCalledNotFromMainQueue:] to find out where", NSStringFromClass([self class]), methodName);
}
- (void)_setNeedsLayout_MainQueueCheck
{
if (dispatch_get_current_queue() != dispatch_get_main_queue())
{
[self methodCalledNotFromMainQueue:NSStringFromSelector(_cmd)];
}
// not really an endless loop, this calls the original
[self _setNeedsLayout_MainQueueCheck];
}シンボルブレークポイントを仕掛けておくと便利。

仕組みは単純だがいいアイディア。

