调试无文档陌生大型项目:用Debug View Hierarchy定位控制器与按钮Action
这种无文档的遗留项目调试确实让人头大,我来分享几个实战中屡试不爽的技巧,帮你快速定位到目标ViewController和控件Action:
一、定位视图所属的ViewController
当Debug View Hierarchy只显示通用类时,响应链和LLDB命令是你的救星:
- 顺着响应链向上找:选中目标视图后,在LLDB控制台依次输入:
重复执行这个命令,直到输出结果中出现po [self nextResponder]UIViewController或项目自定义的ViewController子类(比如XXXDetailViewController),这个就是你要找的控制器。 - 直接读取视图关联的VC:有些UIView内部会保留对ViewController的引用,可以尝试用私有属性直接读取(调试阶段使用完全没问题):
po (UIViewController *)[self valueForKey:@"_viewController"] - 通过内存地址反查类信息:如果拿到了视图的内存地址(比如
0x12345678),用以下命令查看它所属的模块和关联代码:
输出结果里会包含类名、所在文件路径等信息,帮你缩小范围。image lookup --address 0x12345678
二、查找控件触发的Action
对于UIButton、UIBarButtonItem这类控件,用LLDB命令可以直接挖出绑定的Action:
- 查看所有绑定的目标:选中控件后,输入:
输出的内存地址就是Action的接收对象(通常是ViewController)。po [self allTargets] - 获取对应事件的Action方法名:把上面拿到的目标地址替换到下面的命令中,比如目标地址是
0x87654321,事件是UIControlEventTouchUpInside:
输出的字符串数组就是触发的方法名,比如po [self actionsForTarget:(id)0x87654321 forControlEvent:UIControlEventTouchUpInside]@"printButtonTapped:"。 - 用符号断点捕获Action触发:给
UIControl的sendAction:to:forEvent:方法加符号断点,当控件被点击时,断点会触发,此时查看调用栈就能找到Action的实现代码和所属ViewController:
在Xcode的Breakpoint Navigator中点击+→Symbolic Breakpoint,输入符号-[UIControl sendAction:to:forEvent:],运行后点击控件就能捕获到调用流程。
三、进阶调试技巧
- 给ViewController生命周期方法加断点:如果不确定哪个VC加载了目标视图,可以给所有ViewController的
viewDidLoad加断点:
每次有VC加载时都会停下来,结合视图的外观、内存地址就能匹配到目标VC。breakpoint set -r "-[UIViewController viewDidLoad]" - 查看类的所有方法:如果怀疑某个类有动态绑定的方法,可以用runtime函数列出它的所有方法:
po (void)objc_copyMethodList(objc_getClass([self class]), NULL, YES) - 检查Xib/Storyboard关联:如果视图是从界面文件加载的,查看视图的
restorationIdentifier或tag属性,在项目中搜索这些值,可能找到对应的Xib/Storyboard文件,进而找到关联的ViewController。
内容的提问来源于stack exchange,提问作者filo
相关产品推荐
相关产品推荐

