Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the messages sent to an object in Objective-C be monitored or printed out? [duplicate]

Possible Duplicate:
Intercept method call in Objective-C
How to log all methods used in iOS app

For example, a UIViewController object in iOS receives many messages before its view is shown to a user:

  1. viewWillAppear
  2. viewWillLayoutSubviews
  3. viewDidLayoutSubviews
  4. viewDidAppear
  5. ...

because the framework's source code is not viewable, we have to rely on books or blogs, or is there a way to print out or monitor all the messages sent to this object by (1) Objective-C, or (2) by any tool?

like image 714
nonopolarity Avatar asked May 25 '12 06:05

nonopolarity


2 Answers

Rather than my comment, the best approach that I used (and still use) is calling:

(void)instrumentObjcMessageSends(YES);

When I need to start logging all messages and then:

(void)instrumentObjcMessageSends(NO);

Don't forget to add #import <objc/runtime.h>.
When I don't need it anymore. The annoying thing is that the log is created under /tmp/msgSends- and this means that you have to open the terminal and use tail to see it in a readable way.

What is printed is something like this:

- CustomTableViewController UIViewController _parentModalViewController
- CustomTableViewController UIViewController isPerformingModalTransition
- CustomTableViewController UIViewController setInAnimatedVCTransition:
- CustomTableViewController UIViewController viewWillMoveToWindow:
- CustomTableViewController UIViewController isPerformingModalTransition
- CustomTableViewController UIViewController parentViewController
- CustomTableViewController UIViewController _popoverController
- CustomTableViewController UIViewController _didSelfOrAncestorBeginAppearanceTransition
- CustomTableViewController UIViewController parentViewController
- CustomTableViewController UIViewController __viewWillDisappear:
- CustomTableViewController UIViewController _setViewAppearState:isAnimating:
- CustomTableViewController UIViewController automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers

Note: It has been a while since I used this approach for the last time and it looks like this approach doesn't log private methods subclassed. So, if you have a DummyClass with -(void)_dummyMethod as private and then a DummySubClass with a -(void)_dummyMethod implementation, the message will not be logged.

For iOS, this works only on Simulator.

like image 63
bontoJR Avatar answered Nov 04 '22 08:11

bontoJR


You can use DTrace to monitor a running application to see the methods and the classes that are called. You can easily monitor an iOS app running in the Simulator using DTrace on the command line, First you will need to find the PID of the application using ps and then you can run a DTrace probe like the following:

sudo dtrace -q -n 'objc1234:::entry { printf("%s %s\n", probemod, probefunc); }' 

where 1234 is the process ID of the app.

This will produce output that looks like the following:

UIStatusBarItemView -isVisible
UIStatusBarLayoutManager -_positionAfterPlacingItemView:startPosition:
UIView(Geometry) -frame
CALayer -frame
UIStatusBarLayoutManager -_startPosition
UIView(Geometry) -bounds
CALayer -bounds
UIStatusBarItemView -standardPadding
UIStatusBarItem -appearsOnLeft
UIStatusBarItem -leftOrder

If you are only interested in tracing a single class, UIView for example, you could use:

sudo dtrace -q -n 'objc1234:UIView::entry { printf("%s %s\n", probemod, probefunc); }'

If you wanted to trace all calls to dealloc on all classes, you would use:

sudo dtrace -q -n 'objc1234::-dealloc:entry { printf("%s %s\n", probemod, probefunc); }'

Obviously, you could combine these to only see UIView deallocs:

sudo dtrace -q -n 'objc1234:UIView:-dealloc:entry { printf("%s %s\n", probemod, probefunc); }'

If you want to be able to distinguish a specific object of a class you could also print the memory address of the object (self) using the following:

sudo dtrace -q -n 'objc1234:UIView:-dealloc:entry { printf("%s (0x%p) %s\n", probemod, arg0, probefunc); }'

DTrace is extremely powerful and can do considerably more than I've shown here.

like image 14
mttrb Avatar answered Nov 04 '22 08:11

mttrb