编辑:Bison
投稿:bestswifter
"感谢@星夜暮晨(微博)做了此次分享,星星还写了一本书:Xcode江湖录,里面有更多的关于 Xcode 的使用技巧。"
我录下了此次分享的大部分视频,上传在优酷,下面是此次分享的一些文字总结以便日后快速查找,如有理解错误的地方还望指正。
断点
断点(breakpoint)除了普通的断点外,还有五种特殊的形式:
Exception Breakpoint:代码出现问题,抛出异常时触发。
Symbolic Breakpoint:当执行某个符号时触发。
OpenGL ES Error Breakpoint:在 OpenGL ES 错误发生时触发
Test Failure Breakpoint:测试断言失败的时候触发
Swift Error Breakpoint:在 Swift 错误发生时触发
普通断点:
Condition: 返回一个布尔值,只有在布尔值为真时断点才会触发
Ignore:忽略前n次断点,直到第n+1次遇到断点才触发。
Action:断点触发时,Xcode执行的操作,如脚本等。
AppleScript:用于执行脚本,如display dialog "SwiftGG"弹出对话框。
Capture GPU Frame:捕获在断点处 GPU 当前绘制的帧图,用于 OpenGL ES应用的调试。
Debugger Command:相当于在控制台中输入的 lldb 调试命令。
Log Message:将自定义格式、内容的信息输出到控制台,常用的占位符有:%H(断点第几次触发),%B(断点所在的方法的名字)和 @expr@(输出expr的值)。
Shell Command:接收命令文件以及相应的参数列表。Xcode会异步执行 Shell Command。勾选 "Wait until done"表示等待 Shell 命令执行结束后再执行调试工作。
Sound:触发断点的同时播放声音
Automatically continue after evaluating actions:勾选这个选项后,断点不会中断程序运行。
Swift Error Breakpoint:
抛出一个继承自 ErrorType 类型的错误时会触发这个断点。
enum ThisPersonError: ErrorType {
case IsDead
}
func findSomeone(name: String) throws {
if name == "xx" {
throw ThisPersonError.IsDead // 这里将触发断点
}
}
do {
try findSomeone("xx")
}
通过编辑 Swift Error Breakpoint,可以指定响应什么类型的异常。
Exception Breakpoint:
只在 Objective-C 或 C++ 中有用。比如下面这段代码:
int main(int argc, const char * argv[]) {
@autoreleasepool {
@try {
// 打断点后,程序在下一行代码处中断
@throw [NSException exceptionWithName:@"名字" reason:@"原因" userInfo:nil];
}
@catch (NSException *exception) {
NSLog(@"catch断点");
}
}
return 0;
}
如果不添加 Exception Breakpoint,会执行到 @catch代码块。这种断点的编辑界面和以前不太一样:
Exception: 表示响应哪种语言的异常,可以是 Objective-C 或 C++
Break:是在 throw 还是在 catch 中触发这个异常
Symbolic Breakpoint:
符号断点会在某个方法被调用时触发:
比如定义这样的两个函数:
func burnAllCouples() {
print("FFF Couples")
}
func burnAllSingleDogs() {
print("FFF Single Dogs")
}
然后把 Symbol 设置成某个函数的名字:burnAllSingleDogs,这样每次调用burnAllSingleDogs函数都会触发这个断点:
目前 Swift 中,Symbolic Breakpoint 一个比较大的问题是它不支持带参数的方法名。
Test Failure Breakpoint
这在测试的断言失败时触发:
func testExample() {
XCTAssert(1 == 0)
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
比如这个测试断言必然失败,添加 Test Failure Breakpoint 后,程序将在 XCTAssert(1 == 0) 处中断。
内存变量设置
举一个简单的例子:
NSString *string = @"SwiftGG";
NSLog(@"%@", string); // 这一行前面打断点
运行后,右键点击变量:
Print Description of "string":把 string 的信息输出到控制台。
Copy:复制 string 的信息,包含变量名,类名和值。
View Value As:以什么类型的格式来查看变量,默认情况下会自动推断类型。
Edit Value:可以直接修改变量的值。在 Swift中无法修改
Edit Summary Format:修改输出信息的格式,这里的修改会直接影响 Copy 出来的东西。在 Swift 中无效。
Add expression:和断点类似,可以输入新的变量表达式。
Watch:相当于一种新的断点,它观察变量的值。如果发生变化,就像断点一样中断运行。观察点在程序运行结束后会失效。
Quick Look
它可以让源代码以更直观的方式显示出来。
还是以之前的代码举例,把鼠标短暂停留在 string 变量上,会弹出一个窗口,点击其中小眼睛样子的按钮,就可以展开 Quick Look 了:
这种技术在变量不易直观展现出来时会格外有用,比如:
UIColor *color = [UIColor colorWithRed:222/255.0 green:242/255.0 blue:255/255.0 alpha:1];
NSLog(@"%@", color); // 这一行前面打断点
用同样的方法,可以快速看到颜色的各种信息:
PS:在 Swift 中我没能正确打开,星星后来补充说明 Swift 不支持 UIView 和 UIColor。
Quick Look 支持的类型很多,主要有图像、颜色、NSBezierPath、字符串、URL、SpriteKit中的类等。
一般来说,Quick Look 只支持系统自带的类型。如果是自定义的类型,需要实现debugQuickLookObject方法:
class WebContent: NSObject {
var URL = ""
init(URL: String) {
self.URL = URL
}
func debugQuickLookObject() -> AnyObject? {
guard let url = NSURL(string: URL) else { return URL }
return url
}
}
let web = WebContent(URL: "http://swift.gg")
print(web) // 这里加断点
这时候,你就会发现点击小眼睛时,会弹出一个网页。有点像 3D Touch 的重按效果。
代码片段
刚刚的debugQuickLookObject方法不支持智能提示,所以写起来不太方便,很容易出错。这时候就可以为它创建一个代码片段。
首先用一个占位符代替具体的函数实现:
class WebContent: NSObject {
func debugQuickLookObject() -> AnyObject? {
<#Statement#>
}
} <br>
在 Xcode 中输入完最后一个 “>” 时,Xcode 会自动把代码变成这样的形式:
选中这段代码,拖动到 Xcode 右侧的代码片段集合中:
然后双击这段自定义的代码片段并编辑:
主要修改的是 Title 和 Completion ShortCut。以后再输入时,就会有智能提示了:
总结
本期的分享到此结束,主要介绍了四个方面的内容:断点、内存变量设置、Quick Look 和 代码片段。此处应有掌声👏👏👏
再次感谢@星夜暮晨带来的分享。