//
// ViewController.h
// LearnXcode
//
// Created by SharonHu on 15/7/14.
// Copyright (c) 2015年Sharon. All rights reserved.
//
A.过滤列表文件
使用导航器面板底部的搜索框可以过滤源列表文件,例如下图搜索出了名称中带有guide的文件。你可以在任意的导航器视图中使用这个搜索框。
选中一种主题(theme),例如“Midnight”,然后shift选择Source Editor/Console中的所有项,点击Fonts设置字体。Xcode默认字体为menlo,可选Consolas、Monaco等其他等宽字体。
Editing:
Enable Source Control:启用/禁用XCode自带Source Control Manager(SCM)。
Downloads->Components:可下载SDK和Simulator。
shift+command+Y:显示控制台(Show/Hide the debug area)
shift + command + K:清除控制台(Clean)
option+command+R:编辑配置(Edit Scheme
(2)Build
Product -> Edit Scheme(option+command+R)->Info->Build Configuration:选择生成版本(Debug or Release)
command + B:构建(Buid)
(3)Target
一个定义好构建过程的Target成为一个Scheme,可在Scheme中定义Target的六种构建过程:Build/Run/Test/Profile/Analyze/Archive。
一个Target是指在一个Project中构建的一个产品,它包含了构建该产品的所有文件,以及如何构建该产品的配置。
Product -> Edit Scheme(option+command+R)->Manage Schemes可对Scheme的六种构建过程进行配置(可配置项包括Info、Arguments、Options)。
在Project Navigator中选中某个xcodeproj(例如QQ.xcodeproj),将进入Project Setting页面,可点击左侧图标show/hide project and targets list:
点击targets项可分别设置各target的Build Settings;右击可对target进行delete。
(4)Issue & Errors
编译错误(error)和警告(warning)过多时,只显示编译错误:
点击底端的感叹号,即可只显示编译错误,忽略编译警告:
(5)Run
command + R:运行(Run),可能会先编译。若按下control直接运行上次build的product(Run Without Building)。
command + .:停止运行(Stop)
(6)Breakpoint
command + \:当前行设置/取消断点;通过鼠标点击蓝色断点来启用/禁用当前行断点。
command + Y:全局激活或禁用所有的断点,激活进入调试模式(此时断点蓝色可见)。
边列(Gutter)中的断点/警告可右键呼出Reveal in Breakpoint/Issue Navigator。
trick:编辑断点(Edit Breakpoint):
Condition:设置断点的触发条件,例如“i==3”(注意不能有空格)表示当i等于3时该断点才会被触发。
Ignore:设置断点需要被忽略多少次才会中断,若设置成5则表示第6次遇到该断点时才触发。
Action:设置断点触发时的动作,可以为Debugger Command、Log Message、Shell Command或Sound。
例如可设置以下Debugger Command:
(1)读取std::string sig的内存buffer值:mem read sig.c_str() -c sig.size();
(2)打印NSData实例sig:po sig
(7)Debug
F6:下一步(Step Over),逐过程单步调试,不进入函数体。
(fn+)F7:进入(Step Into)函数体。可能与多媒体键有冲突,故需要fn辅助。
(fn+)F8:跳出(Step Out)函数体。可能与多媒体键有冲突,例如呼叫iTunes,故需要fn辅助。
control+command+Y:逐断点(continue)继续执行。
trick:移动指令指针(Move the instruction pointer):
断点调试运行时,可以将绿色指针箭头(Line 47)移动到其他行(Line 49)或其他断点(Line 51)实现跳转执行。
(8)Watch
shift+command+M:Debug Workflow->View Memory。
command+K:Debug Workflow->Clear Console。
Debug Workflow->Show Disassembly When Debugging,可进行汇编指令级调试。
trick:修改变量内存值(change memory value while debugging):
调试运行时,可以在底部的调试窗口(Debug Area,可通过Shift+Command+Y呼出)右键某个变量,除了可以进行View Memory/View Value As之外,还可以选择Edit Value运行时编辑内存变量的值。
这种手动设置指定值,在调试某些难以复现的bug或进行边界测试非常有用,可以避免在验证某个问题时反复改值重新编译。
(9)lldb调试命令
- n/next:step over;
- s/step:step into;
- finish:step out;
- c/continue:goto next breakpoint;
- expr/expression:Evaluate a C/ObjC/C++ expression(动态执行C/ObjC/C++表达式);
// 打印SYSTEM_VERSION(可能要加UIDevice*转换)
- p/print/expr/expression:print as a C/C++ basic variable;
(lldb)p [[[UIDevice currentDevice] systemVersion] doubleValue]// 打印屏幕bounds(可能要加UIScreen*转换)
- po/expr -O/expression -O:Print as an Objective-C object;
(lldb)po NSStringFromCGRect([[UIScreen mainScreen] bounds])
// 打印状态栏frame(可能要加UIApplication*转换)
(lldb)po NSStringFromCGRect([UIApplication sharedApplication].statusBarFrame)
- call:调用。其实上述p/po后接表达式(expression)也有调用的功能,一般只在不需要显式输出,或是无返回值时使用call,用于动态调试插入调用代码。
// 调用后,继续运行程序,view的背景色将变成红色
- 例如可以在viewDidLoad:里面设置断点,然后在程序中断的时候输入以下命令:
(lldb) call [self.view setBackgroundColor:[UIColor redColor]]
- bt(backtrace),打印当前调用堆栈(crash堆栈),“bt all”可打印所有thread的堆栈(相当于command+6的Debug Session Navigation)。
- image:可用于寻址,有多个组合命令,比较实用的一种用法是寻找栈地址对应的代码(行)位置。
- 例如某个UITableView总共有2个section,当其引用的currentSection.index≥2时将会引起[UITableView rectForHeaderInSection:]调用异常,可使用expr动态改值制造crash场景模拟调试。
- 此时crash时的控制台bt显示异常出现在应用层代码“0x00d055b8 - [FACategoryTableView FACategorySectionHeaderDidTouched:] + 744”处(其中0x00d055b8为当前栈(代码段)偏移量,744为栈帧偏移量——PC指针相对函数入口的偏移)。
- 那么具体是FACategoryTableView.m文件哪一行代码调用引起的异常呢?此时通过“image lookup --address”后接bt的call stack中的代码段偏移地址(0x00d055b8)即可定位出异常调用的代码行位置。
- memory write:改写指定地址的内存(Write to the memory of the process being debugged)。可help mem write查看帮助:
x/memory read:dump指定地址的内存(Read from the memory of the process being debugged),后接起止地址或-c指定count加起始地址。可help mem read查看帮助:
Syntax:
memory read
[ ] Command Options Usage:
size指定内存块(block/item)的大小,默认为1byte。
--size
):The size in bytes to use when displaying with the selected format. count指定内存块(block/item)的个数,可配合起始地址使用。
-c
( --count ):The number of total items to display. format指定内容显示格式,格式符同print:c-char,s-string,d-decimal,x-hex。
-f
( --format ):Specify a format to be used for display. Command Samples:
(a)起止地址
(lldb)mem read 0x10b88f0c 0x10b88f0c+9
0x10b88f0c: 39 38 37 36 35 34 33 32 31 987654321
(b)起始地址+内存块count
(lldb)mem read 0x10b88f0c -c 9
0x10b88f0c: 39 38 37 36 35 34 33 32 31 987654321
(c)起始地址+内存块size+内存块count(dump hex format)
(lldb)memory read -s 1 -f x -c 9 0x10b88f0c
0x10b88f0c: 0x39 0x38 0x37 0x36 0x35 0x34 0x33 0x32
0x10b88f14: 0x31
(d)起始地址+内存块size+内存块count(dump char format)
(lldb)memory read -s 1 -f c -c 9 0x10b88f0c
0x10b88f0c: 987654321
(e)起始地址+内存块size+内存块count(dump string format)
(lldb)mem read 0x10b5cf2c -f s -c 1
0x10b88f0c: "987654321"
(f)起始地址+内存块size+内存块count(dump int format)
(lldb)memory read -s 4 -f x -c 3 0x10b88f0c
0x10b88f0c: 0x36373839 0x32333435 0x109f0031
Syntax: memory write
[ [...]]