iOS调试技巧总结

对于大型APP,每次修改重新编译,都需要几分钟时间,因此要在一次运行中尽量多的解决问题,减少编译的次数。
无论是需求的迭代,还是bug的调试,都可能会遇到陌生的代码,对于不熟悉的代码,如何调试呢?

一 打Log

只需要一行输出函数,即可看到各个方法的执行顺序,知道输入、输出值,但是对代码入侵性太强,并且频繁修改消耗过多编译的时间。

二 问写代码的人

最直接最高效。但是如果不经过思考,就直接问,下次遇到类似的问题还是不会。因此我认为最好先自己调试,如果几个小时还无法解决,再请教。
对于遇到的问题,不能仅仅当成一种需要完成的任务,而应该把它当成一种成长的机会,拥有一颗成长型的心态。解决问题的同时,自己也获得了成长,这样就不仅仅是自己在跑步,而是借助公司这辆汽车,达到远超跑步的速度。

三 控制台调试

控制台调试最核心的就是LLDB命令,LLDB是Xcode的默认调试器,它高度利用LLVM项目中的现有库,例如Clang表达式解析器和LLVM反汇编程序。

3.1 执行命令:

expression命令,简写e,最基本的命令。

运用实例:修改View的颜色

有时候我们需要找某个控件,或改某个控件的颜色,但是可能因为层级较多而不是非常明显的情况下,可以先在LLDB尝试修改,看一下预览的效果。

image.png

操作步骤如下:
1.先执行
(lldb) p self.view
查看self.view存储在变量 0变量 2.将0强转为UIView类型,
(lldb) e (UIView *)0 转存到了1
3.使用 1的layer改变颜色 (lldb) e1.layer.backgroundColor=[UIColor redColor].CGColor
4.执行刷新,可以看到对应的UIView立刻生效了。因为断点会终止UI线程,所以这个命令是为了渲染修改后的界面。
(lldb) e [CATransaction flush]

实际运用 暗黑适配

我们团队今年进行了暗黑模式适配,在改别人的代码时,尤其是层级非常多的时候,用此来调整、预览,可以快速定位需要修改的控件。

3.2 打印命令

1)print:简写pri或p,其实print是"expression --"的简写('print' is an abbreviation for 'expression --')。
2)po:用来打印对象
3)call:调用方法。在调试时,想要额外调用一下某个方法,可以使用call命令,如图
call [self callMethod]

image.png

3.3 线程

1)thread jump --by N
功能:在某处断点,跳过之后的N行代码。其效果等同于注释了N行代码。
使用场景:有时候需要注释几行代码,使用此命令,不用重新编译即可立刻看到效果。
2)thread backtrace 查看线程堆栈信息,简写为bt。
3)thread return X
令某个方法直接返回X。

运用实例:

(lldb) thread return XXX

image.png

如图,在25行执行了
(lldb) thread return @"changeReturn"
可以看到- (NSString *)threadReturn 返回的值就变成了@"changeReturn"。

3.4 观察点 watchpoint

作用:可以观察某个变量,在变化时其会自动暂停断点至其相应位置。
使用方式:(lldb) watchpoint set variable name
或者右键其,点击watch variable
注意:如果需要观测self.name,则要写成self->_name。对于观测普通类型的变量,比如button的 state值,_state不存在。在LLDB调试框可以右键这个值。

使用场景:当某个变量值突然被改变,但是又找不到是在哪里改变。使用此即可跟踪其变化。
如果不使用变量观测,就需要重写某个类的某个setter方法。

四、断点调试

先来介绍一下基本的界面:

image.png

这5个按钮,分别是:
1 启动/禁用断点
2 继续执行程序
3 执行下一步
4 进入方法
5 跳出方法
这几个可视化的按钮,在LLDB中都有相应的命令,
1 breakpoint enable/disabled
2 continue
3 next
4 step
5 finish
但是因为按钮更方便,所以通常也不用命令。

4.1 异常断点

异常断点是为了抛出异常时,crash显示到具体的行,而不是main.m中。加上如图的断点即可。

image.png

4.2 符号断点

符号断点是针对某个方法执行的断点,
实际开发中,当我们操作了某个路径会执行A方法,但是A方法用于很多个地方,并不知道具体是在哪里执行的,如果是传统的方法,就全局搜索A方法,全部打上断点。实际上可以用符号断点来解决这个问题。
只要对某个方法打上符号断点,那么所有调用它的地方,都会暂停。

注意:+,-方法写清楚。:之后不能有空格

另外。对于写得比较标准的代码,几个类似的方法,最终应该调用一个统一的方法,叫做全能初始化方法,用NS_DESIGNATED_INITIALIZER标识。只需要对全能初始化方法打符号断点即可。

4.3 编辑断点

image.png

右键点击某一行,即可打开:


image.png

1)Condition

条件断点,对于循环次数非常多的for循环,有时我们需要其在指定的i值时才暂停,或者某两个变量相等时才暂停。

2)Ignore

忽视次数N,即N次之后才会暂停。

3)Action

有些问题通过断点无法解决,因为断点操作需要几秒的操作时间。而轮询类的逻辑,几秒之后其值就变化了。这类问题通常是需要打Log的,但是打Log重新编译消耗过多的时间,如何在不改变代码、重新编译的前提下打Log呢?这时Action就起了很大的作用。

(1)Debugger Command
这个功能相当强大,可以在某一行直接插入新的代码并且不用重新编译。
(2)Log Message
打Log,格式:@exp@,exp指的是变量名。%B:指的是此行所在的方法名。%H:计数器。
缺点:Log Message 适合低频的打印。如果是秒级更新的Log。不适用,每秒打印一次会非常卡。
(3)Sound:当断点到这里时,发出声音,作用和Log一样,只不过从文字变成了声音。
(4)AppleScript,可以执行苹果原生的脚本。
(5)Shell Command,可以执行shell脚本。

五 视图查看

有时候需要对可视的某个控件进行需求,这种情况可以通过视图结构,直接找到对应的类名。虽然不能直接解决问题,但是对于找到问题根源所在,有一定帮助。

5.1原生的Debug View Hierarchy

Debug View Hierarchy,无论是性能性,还是操作方便度上,都比较差。

5.2 Reveal

reveal这是一个专业的团队做的软件,非常好用,只不过需要一些配置。
详见https://www.jianshu.com/p/ced27bec87b4

image.png

5.3 Chisel

Chisel的visualize,facebook出的一个开源LLDB框架,可以在断点的时候查看某个类的视图。

六 LLDB扩展

facebook开源了chisel,可以添加脚本到LLDB。
源码:https://github.com/facebook/chisel
chisel提供了几个命令,对LLDB的功能进一步加强。

1)visualize:预览整个view的图。
相比原生的命令,看到的不仅仅是一个控件的图像,而可以是多个view的组合。

七 网络请求的抓包

对于网络请求,可以在请求的回调中打断点、Log,查看返回的结果。但是对于轮询的请求,打断点太慢,打Log在调试框中展示的内容又太多,会刷屏。因此可以用抓包工具,对所有的请求都进行了整理。
1 charles:古老的抓包工具,不想买软件的话可以免费使用。
2 proxyman,新起之秀,个人认为无论是基础功能,还是界面,都已经超越了Charles。

image.png

3 wireshark,适用于基于TCP/UDP或蓝牙协议的硬件的抓包。

八 静态分析

静态分析,可以在编码的阶段就能检测出一些潜在的问题。
原生的Analyze,以及三方的Clang,Infer,OCLint。

九 参考文献

http://lldb.llvm.org/
https://www.jianshu.com/p/d0b9fd8ffadc
https://developer.apple.com/videos/play/wwdc2018/412/?time=182

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容

  • 前言 今天花了一天的时间终于把iOS的几种常见的调试方法给学习了一下,在这里给大家分享一下LLDB的使用,同时也是...
    Peak_One阅读 10,994评论 5 33
  • 前言 LLDB是个开源的内置于XCode的具有REPL(read-eval-print-loop)特征的Debug...
    Noskthing阅读 18,443评论 10 89
  • 剑未配好,出门已是江湖。 最近一直没有更新简书是因为在开发和测试阶段,有任务,没有进行学习,不过在做任务的时...
    和珏猫阅读 8,134评论 9 75
  • NSLog,po命令和普通断点调试相信每个iOS开发者都会,这里就不作介绍了。 一、Memory Graph Xc...
    wu大维阅读 12,150评论 16 187
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,494评论 16 22