有时候,在查看别人的大型Objective-C程序时,很难知道从哪里开始。
在这种情况下,我认为将每次调用记录到每个非Apple方法都会有所帮助。
有办法吗?基本上,在某个中心位置进行一次更改,并记录每个被调用的方法。优选限于非Apple方法。
答案 0 :(得分:19)
您可以将环境变量NSObjCMessageLoggingEnabled设置为YES。这将写入文件夹/ tmp / msgSends-xxx中的所有消息发送的日志。
答案 1 :(得分:3)
您可以向objc_msgSend()
添加符号断点,并让它在不停止的情况下记录第二个参数。
如果只是一个触摸器任务,如何为自己的方法做到这一点。也许你可以检查一下被调用的类名,并且只为那些类'前缀与你自己的匹配的调用有一个条件断点吗?
答案 2 :(得分:3)
我认为记录每一个电话都不够实用,但是这里有一个建议。
另一方面,如果它是一个大型程序,它最好有一些文档或介绍性评论供人们开始使用代码。
在任何情况下,每个Cocoa应用程序都有一个 applicationDidFinishLaunching ... 方法。这是一个很好的起点。某些应用程序还在Info.plist文件中定义了其主要(或“主窗口”)类。这两件事可能会给你一个提示,告诉你哪些类(特别是视图控制器)是最突出的类,以及在程序运行时哪些方法可能有很长的堆栈跟踪。就像游戏引擎中的游戏循环,或者其他一些经常调用的方法。通过在这样的方法中放置一个断点并查看调试器中的堆栈跟踪,您可以大致了解发生了什么。
如果它是一个UI重的应用程序,查看其中使用的NIB文件和类可能也有助于识别您可能正在寻找的应用程序功能的部分。
另一个选项是启动 Time Profiler 工具,同时选中Hide missing symbols
和Hide system libraries
复选框。这不仅可以让您了解程序中调用方法的鸟瞰图,还可以指出最常被调用的方法。
通过在Time Profiler录制中与您的程序进行交互,您还可以识别程序功能的不同部分,并将它们与您的操作相关联。
答案 3 :(得分:1)
乐器允许您构建自己的“乐器”,这些乐器实际上只是伪装成DTrace
个脚本。使用菜单选项 Instrument >> 构建新乐器并选择选项,例如您要跟踪的库,您在执行特定功能时要记录的内容等。疯狂!
答案 4 :(得分:0)
这是一个有趣的问题。如果解决方案支持多个执行线程并且有某种调用时间线可以随时间报告活动(可能特别是以某种方式绘制用户事件),答案会更有趣。
我通常启动调试器,在主入口点设置一个断点(例如 - applicationDidFinishLaunching:withOptions :)并将其放在调试器中。
在OSX上,还有一些命令行工具(例如样本和堆)可以提供一些见解。
似乎与乐器的某种融合可能真的很酷,但我并不知道某些事情正是你想要的(我现在也想到它)。
如果要记录一个线程号,一个呼叫地址和一些帧详细信息,那么似乎可以在那里绘制呼叫时间线。 Apple的symbolicatecrash脚本中应该存在用于确定相应库(Apple提供的或第三方)的逻辑。