捕获所有 Objective-C 消息并获取 Cocoa 运行时中的对象列表
Posted
技术标签:
【中文标题】捕获所有 Objective-C 消息并获取 Cocoa 运行时中的对象列表【英文标题】:Catch all Objective-C messages and get list of objects in Cocoa runtime 【发布时间】:2010-10-06 13:25:09 【问题描述】:我需要捕获并记录 Cocoa 应用程序中的对象发送的所有消息。而且我还需要运行时对象实例的列表。有可能吗?
【问题讨论】:
对此,不禁要问:为什么?你真正想达到什么目标? 我要画cocoa app的对象图=) 【参考方案1】:使用dtrace
,它已经内置在系统中。请参阅 MacTech 的 this great introductory article。
Dtrace
是系统范围的标准机制,因此您可以记录活动。各种系统 API 通知内核,即每个系统调用、每个objc_msgSend
等都会生成一个可跟踪点,您可以将 dtrace 脚本传递给内核以记录这些活动。它非常强大。
作为练习,请将以下内容放入名为 objc.d
的文件中:
objc$target:::entry
printf("[%s %s]\n", probemod,probefunc);
然后从命令行运行
$ sudo dtrace -q -s objc.d -p 3333
其中 3333 应该是一些 Cocoa 应用程序的 pid。您将获得发送到任何对象的每条消息的日志!呜呜!
【讨论】:
您确实应该将输出重定向到文件以供以后分析。这显然会迅速产生大量的数据。类似sudo dtrace -q -s objc.d -p 3333 > /tmp/allmethodcalls.txt
还请注意,上述内容不一定会捕获每个方法调用。输出速率对于 dtrace 来说太快了,并且在主动计算期间会丢失数千个。【参考方案2】:
您可以通过将NSObjCMessageLoggingEnabled
环境变量设置为YES 来记录应用程序中发送的每条Objective-C 消息。在 Xcode 中选择可执行文件,按 Cmd-I 显示检查器并在那里添加环境变量(参数选项卡)。 Obj-C 消息记录在 /tmp/msgSends-<pid>
中。完成后记得关闭设置,因为日志文件可能巨大。
【讨论】:
您还可以复制当前方案并创建一个启用 msgSends 的新方案。在Run
-> Arguments
-> Environment variables
下。我建议共享该方案,以便团队中的其他人也可以使用它。 “僵尸”计划同样有用。【参考方案3】:
是的,这是可能的,objective-c 是高度动态的,您可以在运行时获得大量信息。仔细看看Objective-C Runtime Reference
【讨论】:
你还没有回答他的问题。哪些 Objective-C 运行时调用将允许记录发送到每个对象的每条消息? 是的,我认为捕获所有消息的唯一方法是用我的自定义方法替换 objc_msgSend 方法。 公平地说,这是一个与问题相匹配的答案以上是关于捕获所有 Objective-C 消息并获取 Cocoa 运行时中的对象列表的主要内容,如果未能解决你的问题,请参考以下文章
Objective-C try/catch异常处理机制原理。
如何使用 Objective-C 在 IOS 中读取和存储系统日志消息
为啥 Objective-C 不显示 OpenCV 捕获的视频的输出帧?