Xcode Debug
Command+Y
快捷键启用或者disable掉所有的断点Command+\
快捷键删除断点
断点的过滤,如下所示:
官方文档:
参考文章:
- My App Crashed, Now What? – Part 1
- My App Crashed, Now What? – Part 2
- Intermediate Debugging with Xcode 8
记录一下学习要点,虽然有的教程已经很老了,但还是很有借鉴意义
基本上有2种类型可能会发生的crash:
- SIGABRT - 也叫
EXC_CRASH
,是一个可控的crash。SIGABRT
出现时在Console会有错误信息输出 - EXC_BAD_ACCESS - 难以调试,通常是内存管理方面的问题
Tips:
1.如果崩溃发生在main.m
中,就设置Exception Breakpoint
2.设置Exception Breakpoint
后,使用po $arg1
调试输出
3.当出现EXC_BAD_ACCESS
错误时,可Enable Zombie Objects
试试
4.注意nibs或者storyboards中的连接是否正确
5.不要忽略编译警告
6.在设备上调试与在模拟器中调试不同
Wireless Debugging on Xcode 9
前提条件:iOS11以上,Xcode9
步骤参考How to use Wireless Debugging on Xcode 9
1.打开Xcode
2.使用USB连接iPhone
3.打开Window>Devices and Simulators
,可看到连接的设备
4.选择设备,勾选Connect via network
5.如果Xcode可以通过网络连接设备,在设备名称后面有一个icon
6.拔掉USB
7.在Xcode中点击Run按钮
设置Debugger Console
如下设置,在每次编译和运行app时,会自动打开Debugger Console
,不用每次都去点
断点
断点Logging
可使用断点来代替NSLog
或者print
进行输出,如下编辑断点:
1.添加Action,选择Log Message
2.这样做后,可以输出log,但是程序会在打断点的地方暂停,所以勾选Automatically continue after evaluating
3.在上面的log中,你输出的是in viewDidLoad
。可使用%B
(方法的名称),%H
(方法被touched的次数)
输出结果为:viewDidLoad() has been touched 1 times
输出某个变量的值,如下,输出newValue
的值:
输出结果为:
The newValue is 1
The newValue is 2
The newValue is 3
断点Expression
上面的断点Logging在输出时没有输出时间戳,这样不是很方便调试
使用断点Expression,添加如下expression NSLog("Loading friends...")
在Using Breakpoints一节中,介绍了断点条件,触发Action
条件
如下在gift.name == "d"
的时候,断点有效,并把gift.name
的值设置为"PS4"
也可以设置迭代的次数
Inspecting Variables with the Variables View
打断点后,variables view中2个重要的按钮,如下的红框:Quick Look button 和 Print Description button,点击这个按钮可以显示信息
如对某个UIImageView
,点击Quick Look
,则可能会显示如下的信息,非常直观:
隐藏Debug区域,在源代码编辑区域也可以如上面进行调试。鼠标在某个变量上停一会儿,就会弹出一个view出来
Shell Script
在一些数据驱动app中,需要清除已存储的数据。可以写个shell脚本,然后在didFinishLaunchingWithOptions
中,设置断点,选择Shell Command
参考Intermediate Debugging with Xcode 8中Starting Up by Tearing Down的介绍
声音
即走到某个断点可以有提示音
MARKs, TODOs, FIXMEs
添加build script
,在有TODO:
或者FIXME:
时,Xcode会给出编译器警告
添加如下的代码到build script
中
TAGS="TODO:|FIXME:"
echo "searching ${SRCROOT} for ${TAGS}"
find "${SRCROOT}" \( -name "*.swift" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($TAGS).*\$" | perl -p -e "s/($TAGS)/ warning: \$1/"
LLDB
Xcode/LLDB: How to get information about an exception that was just thrown?中介绍了结果命令:
(lldb) po $arg1
(lldb) po [$arg1 name]
(lldb) po [$arg1 reason]
可以方便的找出异常的原因,上面博文My App Crashed, Now What? – Part 1介绍的(lldb) po $eax
已经失效,可参考Xcode: One Weird Debugging Trick That Will Save Your Life,步骤:
1.选中objc_exception_throw
2.输入po $arg1
你也可以将 po $arg1
添加到Exception Breakpoint中,如下:
bt 打印最后一次调用堆栈
expr 动态修改变量
如expr username = @"username"
Enable Zombie Objects
当出现EXC_BAD_ACCESS
错误时,可Enable Zombie Objects
试试