可以将发送到Objective-C中的对象的消息进行监视或打印出来吗?

可能重复:
Objective-C中的拦截方法调用
如何logging在iOS应用程序中使用的所有方法

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

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

因为框架的源代码是不可见的,所以我们必须依靠书籍或博客,或者有办法通过(1)Objective-C或(2)通过任何工具来打印或监视发送到该对象的所有消息?

我使用(而且仍在使用)的最好的方法不是我的评论,而是呼吁:

 (void)instrumentObjcMessageSends(YES); 

当我需要开始logging所有消息,然后:

 (void)instrumentObjcMessageSends(NO); 

不要忘记添加#import <objc/runtime.h>
当我不需要它了。 令人讨厌的是,日志是在/tmp/msgSends-下创build的,这意味着你必须打开terminal并使用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 

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

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

您可以使用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是非常强大的,可以做比我在这里显示的更多。