【问题标题】:Log Objective-c message sends on a device记录在设备上发送的 Objective-c 消息
【发布时间】:2014-08-26 21:49:35
【问题描述】:

在模拟器中运行 iOS 应用程序时,有一个环境变量 NSObjCMessageLoggingEnabled 会导致所有 objc_msgSend 调用都被注销到文件中。 (Detailed explanation)。

我正在尝试追踪在我的应用程序中发送的所有消息,但我无法在模拟器中运行它。它必须在物理设备上,因为我通过闪电连接器与硬件交互。出于同样的原因,我无法将调试器附加到进程。

将日志写入磁盘会很有帮助,就像使用 NSObjCMessageLoggingEnabled 创建的那样,但将其写入本地应用程序的 Documents 目录或类似目录。

这可能吗?

【问题讨论】:

  • 我强烈建议您从不同的角度来处理这个问题。日志喷出的数量将是压倒性的,它会记录大量不相关的消息,最终结果将高度依赖于实现。
  • @bbum:值得注意的是,当我打开这个(没有配置日志记录)并尝试在调试器中运行时,我的电脑突然失去了与iOS设备的连接;我必须拔掉它,重新启动它,然后退出并重新启动 Xcode,然后他们才能再次互相交谈。不确定这是否是因为有大量消息通过网络发送而不是本地保存在设备上(我在任何可见的地方都看不到它们......我需要在越狱设备上尝试这个......),但至少看起来可能.
  • @bbum:更重要的是:即使在我使用消息发送检测的 OS X 中,我也通过在某个代码块周围打开并快速关闭 instrumentObjcMessageSends 来完成它,和/或使用条件断点。我无法想象转储然后搜索程序中发送的每条消息的整个混乱,尤其是没有过滤,因为 OP 似乎想要做......
  • @abarnert 是的——我怀疑设备和计算机之间的链接饱和可能会导致您描述的行为。 abarnert 的建议可能有效,如果是这样,重定向日志输出可能会很棘手,但使用类似的恶作剧来发现写入位置或以其他方式重定向它可能是可行的。
  • @funroll 如博客中所述,您需要编写自定义“MyLogObjCMessageSend”方法...github.com/pkjmesra/SCBUTube/blob/master/SCBUTube/Components/…

标签: ios objective-c iphone objective-c-runtime


【解决方案1】:

所有NSObjCMessageLoggingEnabled 所做的只是导致CoreFoundation 在启动和关闭时自动调用instrumentObjcMessageSends

问题在于 Apple 有意将这个函数隐藏在原生 iOS SDK 中,所以你不能直接调用它。

但它在运行时仍然存在于dylib中,所以你总是可以这样做:

#include <dlfcn.h>

typedef void functype(BOOL);
void *libobjc = dlopen("/usr/lib/libobjc.dylib", RTLD_LAZY);
functype *instrumentObjcMessageSends = dlsym(libobjc, "instrumentObjcMessageSends");
if (!instrumentObjcMessageSends) {
    NSLog(@"Couldn't get instrumentObjcMessageSends");
    exit(1);
}
instrumentObjcMessageSends(YES);
NSLog(@"Did it");

我不知道将日志写入何处(如果在任何地方)。我假设你会想打电话给logObjcMessageSends 来注册你自己的ObjCLogProc,正如你链接到的帖子中所解释的那样。

【讨论】:

    猜你喜欢
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 2011-07-26
    相关资源
    最近更新 更多