# SwiftGG交流分享Xcode开发使用技巧

语言：zh-CN
原文：[SwiftGG交流分享Xcode开发使用技巧](<https://allluckly.cn/%E6%8A%95%E7%A8%BF/tuogao24>)
中文：[中文 HTML](<https://allluckly.cn/%E6%8A%95%E7%A8%BF/tuogao24>)
English: [English HTML](<https://allluckly.cn/en/journal/2016-02-26-xcode-development-tips-from-a-swiftgg-discussion/>)
发布于: 2016-02-26T00:00:00+08:00
内容更新于: 2016-02-26T00:00:00+08:00
署名：bestswifter

整理一次 SwiftGG 交流中的 Xcode 使用技巧，介绍异常、符号和测试失败断点，演示调试时查看或修改变量、使用 Quick Look，以及创建可复用代码片段。

原文署名bestswifter，Bison 编辑收录。

[原文所列来源](<http://www.jianshu.com/p/cda4b0fe07e0>)

**阅读前** 这是 2015–2017 年间的技术记录，本次整理未重新运行验证示例。原文为 2016 年交流记录，调试器与语言支持范围按当时版本描述。

编辑：[Bison](<https://allluckly.cn/>)  
 投稿：[bestswifter](<http://www.jianshu.com/p/cda4b0fe07e0>)

> "感谢[@星夜暮晨(微博)](<http://www.jianshu.com/users/ef1058d2d851/latest_articles>)做了此次分享，星星还写了一本书：Xcode江湖录，里面有更多的关于 Xcode 的使用技巧。"

我录下了此次分享的大部分视频，上传在[优酷](<https://speakerdeck.com/cee/swiftgg-show-di-qi-xcode-tips-and-tricks-xing-ye-mu-chen>)，下面是此次分享的一些文字总结以便日后快速查找，如有理解错误的地方还望指正。

### 断点

断点（breakpoint）除了普通的断点外，还有五种特殊的形式：

```
Exception Breakpoint：代码出现问题，抛出异常时触发。
Symbolic Breakpoint：当执行某个符号时触发。
OpenGL ES Error Breakpoint：在 OpenGL ES 错误发生时触发
Test Failure Breakpoint：测试断言失败的时候触发
Swift Error Breakpoint：在 Swift 错误发生时触发
```

普通断点：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/1.png>)

```
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代码块。这种断点的编辑界面和以前不太一样：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/2.png>)

```
Exception： 表示响应哪种语言的异常，可以是 Objective-C 或 C++

Break：是在 throw 还是在 catch 中触发这个异常
```

### Symbolic Breakpoint：

符号断点会在某个方法被调用时触发:

比如定义这样的两个函数：

```
func burnAllCouples() {
    print("FFF Couples")
}

func burnAllSingleDogs() {
    print("FFF Single Dogs")
}
```

然后把 Symbol 设置成某个函数的名字：burnAllSingleDogs，这样每次调用burnAllSingleDogs函数都会触发这个断点：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/3.png>)

目前 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); // 这一行前面打断点
```

运行后，右键点击变量：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/4.png>)

```
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 了：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/5.png>)  
 这种技术在变量不易直观展现出来时会格外有用，比如：

```
UIColor *color = [UIColor colorWithRed:222/255.0 green:242/255.0 blue:255/255.0 alpha:1];
NSLog(@"%@", color);    // 这一行前面打断点
```

用同样的方法，可以快速看到颜色的各种信息：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/6.png>)

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 会自动把代码变成这样的形式：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/7.png>)

选中这段代码，拖动到 Xcode 右侧的代码片段集合中：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/8.png>)

然后双击这段自定义的代码片段并编辑：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/9.png>)

主要修改的是 Title 和 Completion ShortCut。以后再输入时，就会有智能提示了：

![1](<https://allluckly.cn/images/blog/tuogao/tougao24/10.png>)

## 总结

本期的分享到此结束，主要介绍了四个方面的内容：断点、内存变量设置、Quick Look 和 代码片段。此处应有掌声👏👏👏

再次感谢[@星夜暮晨](<http://www.jianshu.com/users/ef1058d2d851/latest_articles>)带来的分享。

---

好文推荐：[Apple Pay强势来袭，开发者应做的事情](<https://allluckly.cn/ios%E6%94%AF%E4%BB%98/Applepay>)

