Caton’s reasons
- CPU related
- Do a lot of I/O operations on the main thread;
- Do network synchronization request on the main thread;
- Multi-thread resource snatching;
- GPU related
- Complex UI, text and text mix too much drawing;
- Lots of rendering algorithms
Caton detection principle
- Monitor the status of the RunLoop to determine if it is stalling. The purpose of RunLoop is to keep the thread busy when there are events to be processed and to put it to sleep when there are no events to be processed. If the thread of the RunLoop takes too long to execute the pre-sleep method and is unable to go to sleep, or if the thread wakes up and takes too long to receive messages and is unable to proceed to the next step, the thread is considered blocked. If the thread is the main thread, it will appear to be stuck.
Six states of Runloop
Typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {kCFRunLoopEntry, // enter loop kCFRunLoopBeforeTimers, // About to process Timer kCFRunLoopBeforeSources, // about to process Source kCFRunLoopBeforeWaiting, // About to enter sleep kCFRunLoopAfterWaiting), / / just wake up from sleep kCFRunLoopExit, / / exit loop kCFRunLoopAllActivities / / loop all status changes}Copy the code
The first step
Listen for state changes in the main thread runloop
CFRunLoopObserverContext = {0,(__bridge void*)self,NULL,NULL}; _runLoopObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, &runloopObserverCallBack, &context); // Add observer CFRunLoopAddObserver(CFRunLoopGetMain(), _runLoopObserver, kCFRunLoopDefaultMode);Copy the code