Instrumenting Objective-C message sendsEdit

Created , updated

Messages are logged to /tmp/msgSends-<pid>:

     + NSObject NSObject initialize
     + NSNotificationCenter NSObject initialize
     + NSNotificationCenter NSNotificationCenter defaultCenter
     + NSNotificationCenter NSObject self
     + NSNotificationCenter NSObject allocWithZone:
     - NSNotificationCenter NSNotificationCenter addObserver:selector:name:object:
     + NSNotificationCenter NSNotificationCenter defaultCenter
     + NSNotificationCenter NSObject self
     - NSNotificationCenter NSNotificationCenter addObserver:selector:name:object:
     + Protocol Protocol _fixup:numElements:
     + NSAutoreleasePool NSObject initialize
     + NSAutoreleasePool NSObject alloc
     + NSAutoreleasePool NSAutoreleasePool allocWithZone:
     + NSAutoreleasePool NSObject self
     + NSThread NSObject initialize
     + NSThread NSObject allocWithZone:
     - NSThread NSThread init

These are the messages sent in response to:

int main (int argc, const char * argv[])
{
    NSAutoreleasePool *pool = [NSAutoreleasePool alloc];
    return 0;
}

My understanding of the syntax is as follows:

  • First column: + indicates a class (factory) method, - indicates an instance method
  • Second column: the class of the object receiving the message
  • Third column: the class of the object that implements the message (note that a class may inherit an implementation from a superclass rather than providing its own)
  • Fourth column: the actual selector

Based on this interpretation, the previously listed message sends indicate the following:

  • The first method called is the NSObject initialize class method
  • The second method is the NSNotificationCenter initialize class method, but NSNotificationCenter doesn’t implement that method, so the superclass implementation is called instead (thus demonstrating why you should make sure that code you write in initialize is either safe to call multiple times, or is protected in some way against repeated execution)

There are two ways of turning on logging:

Setting an environment variable

export NSObjCMessageLoggingEnabled=YES

Enabling/disabling at runtime

instrumentObjcMessageSends(YES);
// do something ...
instrumentObjcMessageSends(NO);

See also