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]; }
シンボルブレークポイントを仕掛けておくと便利。
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ3pH1TKnXa_LRucUA95yVhTIWomOZBB6wmi7uMLNfh4oUiitKyNIPwg8OjuasA-eM7Utzp5PG5jsHfFtgSBDjHnt5uAFXIMlye41SiiKbmWq7e0AVbeLu_UeA7rBscG8sFFMCOXDtKVgh/s320/130214-0021.jpg)
仕組みは単純だがいいアイディア。