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

nop*_*ole 10 xcode objective-c ios

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

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

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

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

bon*_*oJR 16

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

(void)instrumentObjcMessageSends(YES);
Run Code Online (Sandbox Code Playgroud)

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

(void)instrumentObjcMessageSends(NO);
Run Code Online (Sandbox Code Playgroud)

别忘了添加#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
Run Code Online (Sandbox Code Playgroud)

注意:自从我最后一次使用这种方法以来已经有一段时间了,看起来这种方法不会记录子类的私有方法.所以,如果你有一个DummyClass-(void)_dummyMethod私人,然后一个DummySubClass一个-(void)_dummyMethod的实现,该消息将不被记录.

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

  • +1,虽然这只是Mac版.在iOS上,这没有实现. (3认同)

mtt*_*trb 14

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

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

其中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
Run Code Online (Sandbox Code Playgroud)

UIView例如,如果您只对跟踪单个类感兴趣,则可以使用:

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

如果要跟踪所有dealloc类的所有调用,可以使用:

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

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

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

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

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

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


归档时间:

查看次数:

3863 次

最近记录:

14 年,1 月 前