MainThreadChecker
An ability to monitor sub-threads to manipulate UI, and you can also add custom APIs for monitoring (to capture specific stack information when sub-threads monitor certain APIs to help locate problems)
Background introduction
Some people may have never encountered a bunch of logs output from the Xcode console during the development phase because of operating the UI in the sub-thread, which is roughly as follows
In fact, we can give Xcode a Runtime Issue Breakpoint
type selection Main Thread Checker
, and when a sub-thread operates the UI, it will be detected by the system and a breakpoint will be triggered, and at the same time, we can see the stack situation.
The effect is as follows
Problems and Solutions
The above functions are built in Xcode and only available when connected to Xcode for debugging. Online packages cannot be detected.
After exploring that Xcode's implementation of this function is dependent on the libMainThreadChecker.dylib
library on the device, we can force the loading of the library through the dlopen
method so that the non-Xcode environment also has the monitoring function.
In addition, when the UI call is monitored by the sub-thread, in the Xcode environment, the call stack will be output to the console. After testing, libMainThreadChecker.dylib
the output is used. Since NSLog outputs information STDERR
to , we can use NSPipe
and dup2
to STDERR
output Interception, by judging the copy of the information, and then obtaining the monitored UI calls, and finally printing them out through the stack, can help locate specific problems.
libMainThreadChecker.dylib
The library has limitations, and only calls to specific APIs of some specific classes provided by the system will be monitored in sub-threads (for example, the UIView class in the UIKit framework). However, some classes and some APIs we do not want to be called in the child thread, this time libMainThreadChecker.dylib
is not satisfied.
Research on the assembly code of the libMainThreadChecker.dylib
library , it is found that the registration of classes and methods is carried out libMainThreadChecker.dylib
through __main_thread_add_check_for_selector
the method. So if we can also call this method dlsym
through to achieve the main thread call monitoring of custom classes and methods.
In addition, this function can be turned on in the offline debug stage to determine whether it is in the Xcode debug state, which can be realized through the official judgment method provided by Apple .
Those who are unfamiliar with dlopen and dlsym can directly read Apple's official documents, which will not be expanded here .
APM Collection
For those who are interested in APM, you can check out this article that takes you to build an APM monitoring system