百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

iOS 调试技巧:如何利用 LLDB 来 Debug

suiw9 2025-03-13 20:23 10 浏览 0 评论

前言

在开发中一定需要到调试跟踪,但是很多开发者虽然做过很多的项目,但是未必了解开发中有哪些调试命令可以帮助我们开发者更快更好地定位到问题所在。

本篇文章主要是讲解在开发中如何利用LLDB来Debug。首先会讲一些基础知识,主要是帮助新手们学习如何去调试。对于一些比较高级的操作,不会也没有关系,但是如果能够掌握得了的话,会更方便更快速地查找问题。

初步认识LLDB

LLDB是XCode内置的为我们开发者提供的调试工具。至于还不懂什么是调试的,百度一下概念吧,笔者也不知如何描述。看看下图吧,应该就可以大概明白什么是调试了!

我们加了断点,然后在运行到断点处就停了下来,接下来我们看到lldb这里了吗?我们可以通过lldb所提供的命令来操作。

基本调试操作

从上图中,我们八个按钮,我们讲讲前五个按钮:

  • 第一个按钮点击就会收起这一栏目了,也就看不见了。

  • 第二个按钮:如果为蓝色,就是断点有效。如果点击它变成灰色,就是所有断点不起作用。

  • 第三个按钮:是继续的意思,会让程序从断点处恢复继续往下运行,我们点了这个按钮后,应用就会恢复正常运行状态。

  • 第四个按钮是:单步执行的意思,每点这个按钮一次,程序就会从我们断点开始的地方,向下执行一步。

  • 第五个按钮是:进入执行的意思,简单来说就是如果我们当前的断点在一个函数调用上,把么断点会继续进入这个函数的内部进行调试。

  • 第六个按钮是:跳出的意思, 就是如果我们当前在一个函数中,它会跳出当前的函数,回到函数的调用处。

常用p、po、call命令

先看下图:

以下是输入help命令时打印出来的,可以看看这四者有什么不同:

p--('expression--')Evaluateanexpression(ObjC++orSwift)in
thecurrentprogramcontext,usinguserdefinedvariablesand
variablescurrentlyinscope.
po--('expression-O--')Evaluateanexpression(ObjC++orSwift)
inthecurrentprogramcontext,usinguserdefinedvariablesand
variablescurrentlyinscope.
print--('expression--')Evaluateanexpression(ObjC++orSwift)in
thecurrentprogramcontext,usinguserdefinedvariablesand
variablescurrentlyinscope.
call--('expression--')Evaluateanexpression(ObjC++orSwift)in
thecurrentprogramcontext,usinguserdefinedvariablesand
variablescurrentlyinscope.

从官方的描述来看,p、print、call是一样的,但是po就不太一样了,输入一样但是输出不一样。po的输出的是具体对象的内容。

如果想要按照特定的格式来打印,如下:

(lldb)p/sblogName
(__NSCFConstantString*)$9=@"标哥的技术博客"
(lldb)p/xblogName
(__NSCFConstantString*)$10=0x000000010921c0a8@"标哥的技术博客"
(lldb)p/tblogName
(__NSCFConstantString*)$11=0b0000000000000000000000000000000100001001001000011100000010101000@"标哥的技术博客"
(lldb)p/ablogName
(__NSCFConstantString*)$12=0x000000010921c0a8@@"标哥的技术博客"

关于这个规则问题,请查阅打印输出格式化

lldb声明变量

我们可以使用e命令定义变量,然后在调试中使用。看如下的例子:

(lldb)eNSString*$str=@"http://www.henishuo.com"
(lldb)po$str
http://www.henishuo.com

(lldb)eint$count=10
(lldb)p$count
(int)$count=10
(lldb)eNSArray*itemArray=@[@"Test",@"Demo",@"huangyibiao"]
(lldb)po$count
10

我们使用e声明了

开头的变量了吗?我们在声明和使用时也需要加上$符号,与PHP一样!

在调试时,有时候想临时计算一下某个值来比较时,就可以通过这种方式来实现了,再也不用到源代码处添加上声明实现然后添加一句打印了,是否便利了很多?

调用变量的API

当我们在断点处,定义了blogName变量了,因此我们可以通过调试命令来调用

(lldb)po[blogNameuppercaseString]
标哥的技术博客

(lldb)po[blogNamesubstringFromIndex:2]
的技术博客

强转返回值类型

当我们调用API返回值类型不指定时,有时候所打印出来的东西是我们看不懂的,比如下面的获取结果应该是“标”字,但是不同类型打印结果却不一样:

(lldb)po[blogNamecharacterAtIndex:0]
26631

(lldb)po(unsignedint)[blogNamecharacterAtIndex:0]
26631

(lldb)po(char)[blogNamecharacterAtIndex:0]
'a'

(lldb)po(NSString*)[blogNamecharacterAtIndex:0]
0x0000000000006807

(lldb)po(unichar)[blogNamecharacterAtIndex:0]
U+6807u'标'

加断点

如果我们不是在一开始就添加所有的断点,而在调试开始后,想给其它地方加个断点,那么我们可以很方便地通过命令添加断点:

(lldb)b?33
Breakpoint9:where=OCLLDBDebugDemo`-[ViewControlleronButtonClicked:]+53atViewController.m:33,address=0x000000010921a6d5

这是在当前类文件下的33行添加一个断点,添加成功后会有提示,如这里的提示就是成功地在33行添加了断点。当然,添加断点的方式也有好几种,如:

(lldb)b?-[ViewControlleronButtonClicked:]
Breakpoint4:where=OCLLDBDebugDemo`-[ViewControlleronButtonClicked:]+53atViewController.m:33,address=0x000000010921a6d5

实际也是在33行添加断点。不过我们若要使用动态添加断点,就使用b命令加行号就可以了,这种最简单了。

设置断点触发条件

看下图,笔者是怎么设置触发条件的:

我们在NSLog这一行,设置了条件,只有当条件满中时,才会进入断点,不过这里并没有让它进入断点,而条件满足时就发出声音并打印提示语。

这种应用场景主要是在循环遍历数据时,想要断点跟踪就只能通过这种方式了,除非添加NSLog打印,但是这种需要手动添加代码,在调试时才想到要添加一些打印语句,这时候又得重新运行,这太慢了。如果懂得如何设置断点条件,那么就能满足我们的需求了,直接可以设置条件。

常用打印视图层次结构

当我们想要知道某个视图的结构时,可以通过调用recursiveDescription方法来打印出来,那么其结构就一目了然了:

(lldb)po[self.viewrecursiveDescription]?|?|??|?|??|??|(layer)
?|?|

临时刷新界面UI

本demo中,最开始按钮的背景颜色是blueColor,现在我们要在调试过程中修改其背景色为红色,并刷新界面。执行下面的命令行,App界面的按钮背景颜色是:

(lldb)e((UIButton*)sender).backgroundColor=[UIColorredColor]
(UICachedDeviceRGBColor*)$41=0x00007fdd10715b00
(lldb)e(void)[CATransactionflush]

执行上面的命令后,App界面的按钮背景颜色是:

这种做法很有用的哦。当我们在调试UI时,因为颜色类似而不容易区分出来,但是我们可以在调试时通过这样的方式来修改背景色,就不用给源代码写相应的代码来重新运行看效果了。

在调试下运行上面的命令后,按钮的背景颜色就变成了红色了!

最后

写下本篇文章的主要目的是小徒弟不太懂调试,写下此篇文章以帮助小徒弟同时也帮助大家更好地在开发中学会去调试代码。其实还有很多的调试命令,但是不常用,这里就不一一列出来讲解了,大家若想了解更多,可以输入help查看!

相关推荐

俄罗斯的 HTTPS 也要被废了?(俄罗斯网站关闭)

发布该推文的ScottHelme是一名黑客,SecurityHeaders和ReportUri的创始人、Pluralsight作者、BBC常驻黑客。他表示,CAs现在似乎正在停止为俄罗斯域名颁发...

如何强制所有流量使用 HTTPS一网上用户

如何强制所有流量使用HTTPS一网上用户使用.htaccess强制流量到https的最常见方法可能是使用.htaccess重定向请求。.htaccess是一个简单的文本文件,简称为“.h...

https和http的区别(https和http有何区别)

“HTTPS和HTTP都是数据传输的应用层协议,区别在于HTTPS比HTTP安全”。区别在哪里,我们接着往下看:...

快码住!带你十分钟搞懂HTTP与HTTPS协议及请求的区别

什么是协议?网络协议是计算机之间为了实现网络通信从而达成的一种“约定”或“规则”,正是因为这个“规则”的存在,不同厂商的生产设备、及不同操作系统组成的计算机之间,才可以实现通信。简单来说,计算机与网络...

简述HTTPS工作原理(简述https原理,以及与http的区别)

https是在http协议的基础上加了一层SSL(由网景公司开发),加密由ssl实现,它的目的是为用户提供对网站服务器的身份认证(需要CA),以至于保护交换数据的隐私和完整性,原理如图示。1、客户端发...

21、HTTPS 有几次握手和挥手?HTTPS 的原理什么是(高薪 常问)

HTTPS是3次握手和4次挥手,和HTTP是一样的。HTTPS的原理...

一次安全可靠的通信——HTTPS原理

为什么HTTPS协议就比HTTP安全呢?一次安全可靠的通信应该包含什么东西呢,这篇文章我会尝试讲清楚这些细节。Alice与Bob的通信...

为什么有的网站没有使用https(为什么有的网站点不开)

有的网站没有使用HTTPS的原因可能涉及多个方面,以下是.com、.top域名的一些见解:服务器性能限制:HTTPS使用公钥加密和私钥解密技术,这要求服务器具备足够的计算能力来处理加解密操作。如果服务...

HTTPS是什么?加密原理和证书。SSL/TLS握手过程

秘钥的产生过程非对称加密...

图解HTTPS「转」(图解http 完整版 彩色版 pdf)

我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取。所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。...

HTTP 和 HTTPS 有何不同?一文带你全面了解

随着互联网时代的高速发展,Web服务器和客户端之间的安全通信需求也越来越高。HTTP和HTTPS是两种广泛使用的Web通信协议。本文将介绍HTTP和HTTPS的区别,并探讨为什么HTTPS已成为We...

HTTP与HTTPS的区别,详细介绍(http与https有什么区别)

HTTP与HTTPS介绍超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的...

一文让你轻松掌握 HTTPS(https详解)

一文让你轻松掌握HTTPS原文作者:UC国际研发泽原写在最前:欢迎你来到“UC国际技术”公众号,我们将为大家提供与客户端、服务端、算法、测试、数据、前端等相关的高质量技术文章,不限于原创与翻译。...

如何在Spring Boot应用程序上启用HTTPS?

HTTPS是HTTP的安全版本,旨在提供传输层安全性(TLS)[安全套接字层(SSL)的后继产品],这是地址栏中的挂锁图标,用于在Web服务器和浏览器之间建立加密连接。HTTPS加密每个数据包以安全方...

一文彻底搞明白Http以及Https(http0)

早期以信息发布为主的Web1.0时代,HTTP已可以满足绝大部分需要。证书费用、服务器的计算资源都比较昂贵,作为HTTP安全扩展的HTTPS,通常只应用在登录、交易等少数环境中。但随着越来越多的重要...

取消回复欢迎 发表评论: