Tracing Objective-C messages
Tracing is a great debug tool. If you are working on not so well documented/known part of the system looking into inside it can be a big help. As Objective-C is very dynamic it has quite good tracing capabilities. It provides out of the box tools to dump the messages sent. In this artice i’ll show how you can log all the messages sent inside the system, and i’ll also show you can log the messages sent to a particular object.
Tracing of all messages with NSObjCMessageLoggingEnabled
The definite source of debugging on MacOS is tn2124 – The OSX Debugging Magic . Of course it mentious the tracing facility of the objc runtime:
If you set the NSObjCMessageLoggingEnabled environment variable to "YES", the Objective-C runtime will log all dispatched Objective-C messages to a file named /tmp/msgSends-<pid>.
The only issue with this kind of tracing that it creates too much information which is hard enought to analize.
Turning tracing on/off – instrumentObjcMessageSends
Fortunately there is the undocumented function: instrumentObjcMessageSends. It lets you turn on/off tracing progamatically for only parts of the program.
FOUNDATION_EXPORT void instrumentObjcMessageSends(BOOL enable);
- (void)enableTrace:(BOOL)enable
{
instrumentObjcMessageSends(enable);
}
Filtering by class or methods
You can even go further and overwrite the logging callback used by this facility. It can be usefull for limiting messages for certain classes, or redirecting the output to elsewhere.
Tracing messages sent to a particular object
However if you want to log messages sent to a specific instance, you can use an other technique: objective-c message forwarding.
This class is meant to be used by creating a proxy with the initWithOriginal: then using the created instance in place of the original. Note that this it’s use is not 100% transparent, and breaks in many situations, i still find an usefull debugging tool.