Xcode几种调试方法总结

前言:编写代码过程中出现错误、异常是不可避免的。通常我们都需要进行大量的调试去寻找、解决问题。这时,熟练掌握调试技巧将很大程度上的提高工作效率。接下来就说说开发过程中Xcode的调试方法。

1、Enable NSZombie Objects (开启僵尸对象)。

这个技巧主要用来追终重复释放的问题。个人认为,ARC推出以来。项目的基本是基于ARC环境。不用开发者主动去调用release去释放对象,所以不用太在意这个方法。这里就不多做介绍了。想了解该方法的同学请坐飞机

2、 断点调试(全局断点、条件断点)

一、全局断点

NSArray *aa = @[@2,@4];
NSLog(@"%@",aa[3]);

这两行代码,没有添加全局断点时,运行crash,直接就跳到了mian函数,如下图:


1.jpeg

接下来添加全局断点,方法如下图:


2.jpeg

添加之后运行,奔溃后,程序停留在了crash那行代码。
3.jpeg

是不是很方便,很省事。哈哈!(ps 不过有的crash,这种方式定位不到)

二、条件断点:设置断点触发的条件,方便开发者对特定情况进行调试

如下图:
在for循环中添加一个断点。右击断点选择”Edit BreakPoint”,然后设置断点触发条件。


4.jpeg

这个例子当 “i==5”时,断点触发,如下图:


5.jpeg

3、Static Analyzer (静态分析)

Static Analyzer主要用于分析内存,避免内存泄漏。主要对以下情况进行分析。
未使用的实例变量、未初始化的实例变量、类型不兼容、无法达到的路径、引用空指针
使用:command + shift +B,如下图就能轻松找到可能内存泄漏的代码,然后我们根据代码环境进行修复就可以了(ps:有的内存泄漏可能检测不出来,还是需要我们在写代码时对内存这块多留点心。)


6.jpeg

4、 LLDB调试器

这个方法是我今天主推的方法。比较高级,也更加灵活、方便。
随着Xcode5,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器。其实Xcode已经帮我们完成了大部分工作,而且很多东西也可以在Xcode中直接看到。所以这里我们只列举常用的命令。
打印:p,print的缩写:该命令如果打印的是简单类型则会列出简单类型的的类型和值,如果是对象会打印出对象的地址。
po,print Object 的缩写,用于输出对象
如下如,当运行到断点处时,控制台就会出现LLDB的调试命令行。我们只需在这里进行调试。

7.jpeg

expr:expression的缩写,可以在调试时动态执行指定表达式,并将结果打印出来。常用于在调试过程中修改变量的值。
如上图,你在控制台输入
expr a=2
你就能看到
(NSInteger) $11 = 2
这是a的值就被动态改成了2
除此之外,还可以使用这个命令生成一个新的对象,如:
expr int $b = 0
p $b 这条命令用于输出新申明对象的值(注意要加$)
image: image命令可用于寻址,有多个组合命令,在控制台输入help image可查看image的用法。比较实用的用法是用于寻找栈地址对应的代码位置,下面我们来举个例子:

NSArray *array = @[@1,@2];
NSLog(@"%@",array[2]);

这段代码很明显会crash,运行之后抛出下面的异常

2017-03-23 22:26:11.014 Test[3631:136626] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000104f28f45 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001049a2deb objc_exception_throw + 48
    2   CoreFoundation                      0x0000000104e17b14 -[__NSArrayI objectAtIndex:] + 164
    3   Test                                0x00000001044a5829 -[ViewController viewDidLoad] + 265
    4   UIKit                               0x0000000105467cc4 -[UIViewController loadViewIfRequired] + 1198
    5   UIKit                               0x0000000105468013 -[UIViewController view] + 27
    6   UIKit                               0x000000010534151c -[UIWindow addRootViewControllerViewIfPossible] + 61
    7   UIKit                               0x0000000105341c05 -[UIWindow _setHidden:forced:] + 282
    8   UIKit                               0x00000001053534a5 -[UIWindow makeKeyAndVisible] + 42
    9   UIKit                               0x00000001052cd396 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4131
    10  UIKit                               0x00000001052d39c3 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1750
    11  UIKit                               0x00000001052d0ba3 -[UIApplication workspaceDidEndTransaction:] + 188
    12  FrontBoardServices                  0x0000000107c83784 -[FBSSerialQueue _performNext] + 192
    13  FrontBoardServices                  0x0000000107c83af2 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
    14  CoreFoundation                      0x0000000104e55011 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    15  CoreFoundation                      0x0000000104e4af3c __CFRunLoopDoSources0 + 556
    16  CoreFoundation                      0x0000000104e4a3f3 __CFRunLoopRun + 867
    17  CoreFoundation                      0x0000000104e49e08 CFRunLoopRunSpecific + 488
    18  UIKit                               0x00000001052d04f5 -[UIApplication _run] + 402
    19  UIKit                               0x00000001052d530d UIApplicationMain + 171
    20  Test                                0x00000001044a5baf main + 111
    21  libdyld.dylib                       0x000000010764c92d start + 1
    22  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

现在我怀疑出错的地址是0x00000001044a5829(可根据执行文件名或最小的栈地址判断)为进一步精确定位我们可输入以下命令image lookup --address 0x00000001044a5829
命令执行后返回结果如下:

 Address: Test[0x0000000100001829] (Test.__TEXT.__text + 265)
 Summary: Test`-[ViewController viewDidLoad] + 265 at ViewController.m:21

由此,我们可以看出出错的地方是ViewController.m文件的第21行。
我们还可以使用image lookup命令查看具体的类,如下:

(lldb) image lookup --type UIView
Best match found in /Users/jamalping/Library/Developer/Xcode/DerivedData/Test-gviuudbzlyhssmanjxpwhchdbscz/Build/Products/Debug-iphonesimulator/Test.app/Test:
id = {0x00001e8d}, name = "UIView", byte-size = 8, decl = UIView.h:144, clang_type = "@interface UIView : UIResponder
@property ( getter = isUserInteractionEnabled,setter = setUserInteractionEnabled:,assign,readwrite,nonatomic ) BOOL userInteractionEnabled;
@property ( getter = tag,setter = setTag:,assign,readwrite,nonatomic ) NSInteger tag;
@property ( readonly,getter = layer,setter = <null selector>,nonatomic ) CALayer * layer;
@property ( readonly,getter = isFocused,setter = <null selector>,nonatomic ) BOOL focused;
@property ( getter = semanticContentAttribute,setter = setSemanticContentAttribute:,assign,readwrite,nonatomic ) UISemanticContentAttribute semanticContentAttribute;
@end
"

**call **
call:即调用,如我们在viewDidLoad: 设置一个断点,在程序中断的时候输入call self.view.backgroudColor = [UIColo redColor]继续运行程序,view就变成红色了,在调试的时候灵活运用call命令可以达到事半功倍的效果。
**参考: **
objc.io#19#与调试器共舞 - LLDB 的华尔兹
浅谈LLDB调试器
Getting interactive with the debugger

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

推荐阅读更多精彩内容

  • 剑未配好,出门已是江湖。 最近一直没有更新简书是因为在开发和测试阶段,有任务,没有进行学习,不过在做任务的时...
    和珏猫阅读 8,145评论 9 75
  • 转载 与调试器共舞 - LLDB 的华尔兹: https://objccn.io/issue-19-2/ 推荐:i...
    F麦子阅读 3,331评论 0 10
  • [转]浅谈LLDB调试器文章来源于:http://www.cocoachina.com/ios/20150126/...
    loveobjc阅读 2,487评论 2 6
  • LLDB的Xcode默认的调试器,它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。平时用Xc...
    CoderSC阅读 1,349评论 0 2
  • 白百何这事还没完。今天中午,全明星探曝出某知情人谈白百何出轨的语音。据该知情人语音爆料,白百何陈羽凡早在两年半以前...
    鱼乐圈没有圈阅读 155评论 0 5