Xcode IDE概览
Xcode 页面主要分为以下四个部分:
- 工具栏(ToolBar area):主要负责程序运行调试,编辑器功能区域的显示 / 隐藏;
- 编辑区(Editor area):代码编写区域;
- 导航区(Navigator area):展示工程文件列表;
- 调试区(Debug area):用于程序调试,查看对象信息,打印日志等。
导航区
详细功能分别为:
- 项目导航器(Project navigator):在工程中添加、删除、分组以及管理文件、查看文件、或者在编辑取区编辑其内容
- 版本控制管理器 (Source Control navigator): 查看源代码控制工作副本、分支、提交、标签和远程代码库。
- 符号导航器(Symbol navigator):集成所有在工作区中定义的符号,从根本上说符号就是编辑器所能识别的东西,eg:OC 类、结构体、枚举类型、全局变量等
- 搜索导航器(Find navigator):在项目和框架中查找任何字符串、引用、定义以及调用层级。
- 问题导航器(Issue navigator):可查看在打开、分析以及构建项目过程中发现诊断、警告以及错误信息
- 测试导航器(Test navigator):创建、管理、运行以及检查单元测试
- 调试导航器(Debug navigator):查看项目运行的 CPU、内存、磁盘、网络等情况,详细介绍
- 断点导航器(Breakpoint navigator):添加、删除和编辑断点。
- 报告(日志)导航器(Report navigator):查看构建、运行和调试项目以及源代码控制任务的历史记录。
分别对应快捷键为:Command + 1 ~ 9
Xcode 常用快捷键
文件操作快捷键
作用 | 快捷键组合 |
---|---|
在当前工程中创建一个新文件 (一般包括.h 和 .m 文件) | Command + N |
在当前工程中创建一个新工程 | Command + Shift + N |
在工程中关闭当前正在屏幕中显示的文件 | Command + W |
最小化 xcode 编译器窗口 | Command + M |
调试快捷键
作用 | 快捷键组合 |
---|---|
编译并运行 | Command + R |
编译 | Command + B |
强制退出 | Command + Q |
停止运行 | Command + . |
继续 (到下一个断点,如果没有则执行到结束) | Command + Control + Y |
单步调试 | F6 |
跳入某函数 | F7 |
跳出某函数 | F8 |
添加 / 删除断点 | Command + \ (光标必须在指定的行) |
静态代码分析 | Command + Shift + B |
Xcode 常用调试方法
断点
断点里面根据作用和功能也有很多种类:普通断点、条件断点、异常断点、符号断点等。
普通断点
当程序运行到断点处时会暂停运行。比如断点打在 30 行,那么程序就会停在 30 行(注意:程序只运行到了前 29 行,第 30 行其实还没有被执行。)。只要在代码行旁边点击,就能添加一个断点,再次点击,断点变成浅蓝色,就能让断点不可用(disable 了,仍然存在,只是不起作用了)。
条件断点
打上断点之后,对断点进行编辑,设置相应过滤条件。单击右键会弹出选项框,四个选项分别为:
- Edit BreakPoint:编辑断点。
- Disable BreakPoint:断点失效。(相当于上边说到的单击断点变成浅蓝色,断点失效)
- Delete BreakPoint:删除断点。
- Reveal in BreakPoint Navigator:在左边的断点树状结构表明该断点。
这里我主要用到的是第一个:Edit BreakPoint。这里面设置断点的筛选条件(双击断点也可以快速进入编辑断点的对话框)。
- Condition: 返回一个布尔值,当布尔值为真触发断点,一般里面我们可以写一个表达式。
- Ignore: 忽略前 N 次断点,到 N+1 次再触发断点。
- Action: 断点触发事件,分为以下六种:
- AppleScript:执行脚本。
- Capture GPU Frame:用于 OpenGL ES 调试,捕获断点处 GPU 当前绘制帧。
- Debugger Command:和控制台中输入 LLDB 调试命令一致。
- Log Message:输出自定义格式信息至控制台。
- Shell Command:接收命令文件及相应参数列表,Shell Command 是异步执行的,只有勾选 "Wait until done" 才会等待 Shell 命令执行完在执行调试。
- Sound:断点触发时播放声音。
- Options (Automatically continue after evaluating actions 选项):选中后,表示断点不会终止程序的运行。
异常断点
利用 Xcode 进行软件开发时,总避免不了出现异常而导致程序崩溃,但有时候又不知道哪里出错,只能利用下断点一点一点测试,虽然也能测出来但总是不能一步到位。其实 Xcode 有个异常断点,可以在导致程序崩溃或者引发异常的那行代码上自动设置断点。
步骤 1⃣️:(1)打开断点导航器 -> (2) 点击下方➕号 ->(3)选择 "Exception Breakpoint"
步骤 2⃣️:按照上述步骤选择之后,将会看到异常断点的编辑条件,在这里你可以根据自己的需要编辑自己的异常断点条件:
Exception 选项可以让你选择响应 Objective-C 对象抛出的异常,也可以选择响应 C++ 对象抛出的异常。 Break 则是选择断点所接收的异常,是接收 "Throw" 语句抛出的异常还是 Catch 语句的。
步骤 3⃣️:运行程序,解决问题后。删除该异常断点。
符号断点
Symbolic Breakpoint 为符号断点,可以针对某一个方法 (函数) 设置断点并暂停执行;有时候,我们并不清楚会在什么情况下调用某一个函数,那我们可以通过符号断点来跟踪获取调用该函数的程序堆栈。
步骤 1⃣️:如同设置异常断点一样,在点击➕之后,选择 "Symbolic BreakPoint"
步骤 2⃣️:编辑要断点的方法名、条件等。
- Symbol:填入你想设置断点的方法(例如:-[NSException raise],- 号是实例方法,+ 号是类方法)。
- Module:填入要设置断点的方法或函数是否在位于 dylib 中,默认不填。
- Conditon:填入条件,例如:(BOOL)[item isEqualToString:@"test"] 前面的(BOOL)是必须的。否则 console 会提示类型不符合,导致条件不能生效。意思是 item(NSString)是 test 时停下。
- Ignore:忽略几次。
- Action:可在程序断点执行后增加额外动作(Applescript,捕捉动画帧速,调试器命令(lldb),输入 log 记录,终端命令(shell), 播放声音)例如:Debugger Commond 中可填入
- po item 输出 item 变量的值
- bt 表示输出 方法调用堆栈信息
步骤 3⃣️:假如输入的方法名为: [UIView init],此时就可以看到新加的断点方法。
步骤 4⃣️:运行项目,此时 Xcode 会停在你的断点方法中。
日志输出
关于日志输出,最先可能想到的是在代码编辑区的 NSLog (),虽然在打印的时候很清晰,但是缺点就是在我们需要在想要打印的位置添加 NSLog 代码并重新运行项目,这样会比较耽误时间,影响开发效率,而我们在调试过程中用的比较多的是打断点,然后 p 或者 po 一下。这个 p 和 po 就是 LLDB 中的打印(print)命令。像下图中,在 29 行中打了断点,在下方控制台的右边会出现一个 "lldb" 的对话窗。
help 命令
在 lldb 中输入 help,然后回车,可以看到 lldb 的一些常用的命令,如下图所例。常用的命令为 po、p、expression、call...
expression 命令
expr 或 e : expression 的缩写,可以在调试时动态执行指定表达式,并将结果打印出来,是 LLDB 调试命令中最重要的命令,我们以后经常用到的 p 和 po 命令的鼻祖 。expression 命令主要有两个功能:
- 执行表达式
- 输出返回值
注意:虽然 expression 命令有输出返回值功能,但是在日常调试过程中并不常用,一般这类打印功能被 p 和 po 命令代替,而 expr 常用于在调试过程中修改变量的值。
p & print & e & call 命令
po 命令
oc 里所有的对象都是用指针表示的,打印出来的是对象的指针,而不是对象本身,可以采用 -o 来打印对象本身为了更加方便的时候,LLDB 为 "expression -o --" 定了一个别名 :po ,它可用于输出 OC 对象和对象的信息。
call 命令
方法调用:在断点调用某个方法,并输出此方法的返回值,一般常用于方法的调用。
image 命令
常用命令如下:
- image list:查看工程中使用的库
- image lookup:可以用来查找可执行文件或共享库的原始地址,当程序崩溃的时候,可以使用这条命令来查找崩溃所在的具体位置。
如下代码:
运行此代码,崩溃信息如下:
上述 crash 根据调用栈信息如何定位到具体哪行代码出现问题:
我们可以使用在 LLDB 中使用 image lookup -a 地址 或者 image lookup --address 地址 命令进行定位。
通过逐步查看调用栈信息,我们可以看到的是在 -[ContainerViewController viewDidLoad] 方法中也就是在 ContainerViewController.m 文件的第 36 行数组越界导致的崩溃。
LLDB 调试对话窗
从左到右功能依次详细介绍:
- 显示 / 隐藏控制台
- 断点信息:如果为蓝色,就是断点有效。如果点击它变成灰色,就是所有断点不起作用。
- continue:点击这个按钮程序就会从当前断点恢复运行,直到下一个断点
- step over :点击这个按钮会一步一步的运行,方便调试
- step in:点击这个按钮会进入函数内部
- step out:点击这个按钮会跳出函数内部,回到函数调用处,一般与左边的按钮对应使用
- 视图调试器:查看图层,在第 2.4 四节中详细介绍
- 内存结构图(menory graph):方便查看堆栈信息
- 覆盖调试器的环境变量设置
- 模拟器定位开关
性能检测
静态分析:通过对代码静态分析,找出代码潜在的错误,如内存泄漏、空引用、未使用函数等。方法:菜单 "Product"->"Analyze" 或者使用快捷键 Shift + Command + B ,然后想办法消灭蓝箭头。
具体参考我的这篇博客: