发送到Objective-C中的对象的消息是否可以被监视或打印出来?

时间:2012-05-25 06:21:20

标签: objective-c ios xcode

  

可能重复:
  Intercept method call in Objective-C
  How to log all methods used in iOS app

例如,iOS中的UIViewController对象在向用户显示其视图之前会收到许多消息:

  1. viewWillAppear
  2. viewWillLayoutSubviews
  3. viewDidLayoutSubviews
  4. viewDidAppear
  5. ...
  6. 因为框架的源代码不可见,我们必须依赖书籍或博客,或者有办法打印或监控发送到该对象的所有消息(1)Objective-C,或(2)用什么工具?

2 个答案:

答案 0 :(得分:16)

而不是我的评论,我使用(并且仍在使用)的最佳方法是调用:

(void)instrumentObjcMessageSends(YES);

当我需要开始记录所有消息然后:

(void)instrumentObjcMessageSends(NO);

不要忘记添加#import <objc/runtime.h> 当我不再需要它了。令人讨厌的是,日志是在/tmp/msgSends-下创建的,这意味着您必须打开终端并使用tail以可读的方式查看它。

印刷的内容是这样的:

- 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

注意:自从我最后一次使用这种方法已经有一段时间了,看起来这种方法不会记录子类的私有方法。因此,如果DummyClass -(void)_dummyMethod为私有,然后DummySubClass-(void)_dummyMethod,则不会记录该消息。

对于iOS,这仅适用于模拟器。

答案 1 :(得分:14)

您可以使用DTrace监视正在运行的应用程序,以查看调用的方法和类。您可以在命令行上使用DTrace轻松监控在Simulator中运行的iOS应用程序。首先,您需要使用ps查找应用程序的PID,然后您可以运行如下所示的DTrace探测器:

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

其中1234是应用的进程ID。

这将产生如下所示的输出:

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

如果您只想跟踪一个班级,例如UIView,您可以使用:

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

如果您想在所有课程中跟踪对dealloc的所有来电,您可以使用:

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

显然,您可以将这些结合起来只看UIView dealloc s:

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

如果您希望能够区分某个类的特定对象,您还可以使用以下命令打印该对象的内存地址(self):

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

DTrace非常强大,可以做得比我在这里显示的要多得多。