不会吧!你还在用这么麻烦的方法调试?

250 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情


前言

你还在苦恼,使用真机调试时,都要重新Run一下Xcode吗?

你还在苦恼,循环太多,找不到关键值而需要每次点step over吗?

你还在苦恼,程序发生crash,但是控制器打印了一堆看不懂的东西,不知道在哪发生的错误?

...

别急,今天这篇文章就来给你的小脑瓜开开窍。


正文

无论是多久工作了多久的iOSer,心里是否有个疑问,Xcode这个IDE,是否还有咱们不知道的,方便操作的功能,(就像Excel一样),今天咱们就来说说 Xcode中的LLDB

LLDB 是 macOS 上 Xcode 中的默认调试器,支持在桌面和 iOS 设备和模拟器上调试 C、Objective-C 和 C++。

所以说,想玩转Xcode,LLDB的学习是分不开的。

今天就从三个实际应用来说说,如何使用LLDB。

p & po

相信大家在打断点时,都应该知道 po 这个关键字把,ppo实际都是expression命令

po用来输出一个指针指向的对象的值。


(lldb) po button
<UIButton: 0x7fb39c50c1f0; frame = (30 100; 100 30); opaque = NO; layer = <CALayer: 0x608000031a60>>

p 是用于执行一段表达式

(lldb) p button
(UIButton *) $1 = 0x00007fb39c50c1f0

当咱们在程序运行的时候,想去修改一个label的属性时(比如背景颜色),大多数时候,是不是要重新修改代码,然后重新Run一下看看效果。

就如下图

截屏2022-06-01 上午10.57.05.png

咱们想修改iphone11这个label的背景色,以前是透明的,现在想改成红色,要怎么操作?

这里就可以用上 p 这个关键字了,咱们先打断点。

截屏2022-06-01 上午11.01.59.png

p textLB.backgroundColor = .red

将 textLB 的背景色变为红色

截屏2022-06-01 上午11.04.38.png

然后点击回车,继续执行后面的。

就可以惊奇的发现

截屏2022-06-01 上午11.05.46.png

iphone11这个label的背景色,变红了。

所以,知道用法了吗?

断点(Breakpoint)

断开的感情线,我不要做断点~~ 咳咳,此断点非彼断点。

说正事。

断点这个功能,个人感觉还是比较好用的,前提是你要会用。

比如要循环数组里的元素,在不改变代码的情况下,查看数组里的第3个元素的值

截屏2022-06-01 上午11.20.50.png

通常的情况下,只有改变代码,在循环中加入if。

这里断点的编辑,就可以帮你在不改变代码的情况下,完成操作。

截屏2022-06-01 上午11.23.11.png

咱们点击断点的标志,在弹出框里,可以看到,有个 Condition的输入框,咱们在里面输入,obj == 4,然后再次执行代码。就会发现,当obj等于4的时候,程序才会停止,其他的时候都不会。

截屏2022-06-01 上午11.26.00.png

所以这样就在开发中,节省许多调试时间,直捣黄龙。

断点行为 (Action)

当执行到断点时,咱们可以做一些操作,比如一些Shell指令,打log等。

这里,可以按照如下图所示,执行一下。记得外放声音哦

截屏2022-06-01 上午11.31.04.png

image lookup

当我们知道一个地址,想查找这个地址对应的位置,可以使用image lookup --address

例子:

2022-6-1 10:51:06.301 TLLDB[25086:246169] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 1 beyond bounds for empty NSArray'

*** First throw call stack:

(

    0   CoreFoundation                      0x000000010accde65 __exceptionPreprocess + 165

    1   libobjc.A.dylib                     0x000000010a746deb objc_exception_throw + 48

    2   CoreFoundation                      0x000000010ac7c395 -[__NSArray0 objectAtIndex:] + 101

    3   TLLDB                               0x000000010a1c3e36 -[ViewController viewDidLoad] + 86

    4   UIKit                               0x000000010b210f98 -[UIViewController loadViewIfRequired] + 1198

    5   UIKit                               0x000000010b2112e7 -[UIViewController view] + 27

这个是简单的数组越界,但要知道是那个界面的数组发生越界,就需要使用 image lookup

下面执行

(lldb) image lookup -a 0x000000010a1c3e36

      Address: TLLDB[0x0000000100000e36] (TLLDB.__TEXT.__text + 246)

      Summary: TLLDB`-[ViewController viewDidLoad] + 86 at ViewController.m:32

0x000000010a1c3e36 就是 [ViewController viewDidLoad]的地址

执行后发现 这个文件叫 ViewController.m 并且 发送crash的地方在32行

是不是很方便,妈妈再也不用担心我找不到crash了

当然现在有很多插件也支持这个功能,但是原理都是使用 image lookup

结语

Xcode的调试方式还有很多,这篇文章只能用于抛装引玉,还是需要咱们在开发的过程中,多多学习,多多进步,才能更加方便。

毕竟,懒才是人类进步的源泉。