Xcode 调试方法总结
前言:编写代码过程中出现错误、异常是不可避免的。通常我们都需要进行大量的调试去寻找、解决问题。这时,熟练掌握调试技巧将很大程度上的提高工作效率。接下来就说说开发过程中Xcode的调试方法。
1. Enable NSZombie Objects (开启僵尸对象)。 
这个技巧主要用来追终重复释放的问题。个人认为,ARC推出以来。项目的基本是基于ARC环境。不用开发者主动去调用release去释放对象,所以不用太在意这个方法。这里就不多做介绍了。想了解该方法的同学请 坐飞机 
2. 断点调试(全局断点、条件断点) 
一、全局断点:
NSArray *aa = @[@2,@4];
NSLog(@"%@",aa[3]);
- 1
 - 2
 
这两行代码,没有添加全局断点时,运行crash,直接就跳到了mian函数,如下图:
接下来添加全局断点,方法如下图:
添加之后运行,奔溃后,程序停留在了crash那行代码。
是不是很方便,很省事。哈哈!(ps 不过有的crash,这种方式定位不到)
二、条件断点:设置断点触发的条件,方便开发者对特定情况进行调试 
如下图: 
在for循环中添加一个断点。右击断点选择”Edit BreakPoint”,然后设置断点触发条件。 
这个例子当 “i==5”时,断点触发,如下图: 
3. Static Analyzer (静态分析) 
Static Analyzer主要用于分析内存,避免内存泄漏。主要对以下情况进行分析。 
未使用的实例变量、未初始化的实例变量、类型不兼容、无法达到的路径、引用空指针 
使用:command + shift +B,如下图就能轻松找到可能内存泄漏的代码,然后我们根据代码环境进行修复就可以了(ps:有的内存泄漏可能检测不出来,还是需要我们在写代码时对内存这块多留点心。)
4. LLDB调试器 
这个方法是我今天主推的方法。比较高级,也更加灵活、方便。 
随着Xcode5,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器。其实Xcode已经帮我们完成了大部分工作,而且很多东西也可以在Xcode中直接看到。所以这里我们只列举常用的命令。 
打印:p,print的缩写:该命令如果打印的是简单类型则会列出简单类型的的类型和值,如果是对象会打印出对象的地址。 
po,print Object 的缩写,用于输出OC对象 
如下如,当运行到断点处时,控制台就会出现LLDB的调试命令行。我们只需在这里进行调试。 
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]);
- 1
 - 2
 
这段代码很明显会crash,运行之后抛出下面的异常
2016-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
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 - 23
 - 24
 - 25
 - 26
 - 27
 - 28
 
现在我怀疑出错的地址是0x00000001044a5829(可根据执行文件名或最小的栈地址判断)为进一步精确定位我们可输入以下命令image lookup --address 0x00000001044a5829 
命令执行后返回结果如下:
Address: Test[0x0000000100001829] (Test.__TEXT.__text + 265)
Summary: Test`-[ViewController viewDidLoad] + 265 at ViewController.m:21
- 1
 - 2
 
由此,我们可以看出出错的地方是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
"
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 
call 
call:即调用,如我们在viewDidLoad: 设置一个断点,在程序中断的时候输入call self.view.backgroudColor = [UIColo redColor]继续运行程序,view就变成红色了,在调试的时候灵活运用call命令可以达到事半功倍的效果
Xcode 调试方法总结的更多相关文章
- Mac OS X 10.9 Mavericks安装后,Xcode调试时模拟器黑屏的处理方法
		
请耐心的等下去吧,少年! 装了Mac OS X 10.9 Mavericks的同学,如果碰到Xcode调试App时,模拟器黑屏(重置也无效),请耐心的等下去吧,大约10来分钟左右黑屏就会消失,App启 ...
 - Xcode 调试技巧 --常用命令和断点
		
Xcode 中的调试技巧与我们的日常开发息息相关,而这些调试技巧在我们解决Bug时,常常有事半功倍的作用,经常会用到的有各种断点 和 命令.而这些调试技巧也经常会在面试中问到,所以不知道的就来看看吧. ...
 - IOS调试技巧:当程序崩溃的时候怎么办 xcode调试
		
转自:http://www.ityran.com/archives/1143 ------------------------------------------------ 欢迎回到当程序崩溃的时候 ...
 - Linux环境下段错误的产生原因及调试方法小结(转)
		
最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且 项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的“段错误”(Segmentation F ...
 - linux Ubuntu(Segmentation fault)段错误出现原因及调试方法
		
在linux下编译了一个程序,尝试运行的时候出现: Segmentation fault (core dumped) 初步确认为...完全不知道是什么玩意. 于是找度娘了. ----------- ...
 - kernel启动console_init之前console不可用时发生crash的调试方法
		
http://code.google.com/p/innosoc/wiki/KernelBootCrashDebug 注: 如在i386_start_kernel中加入:early_printk(&q ...
 - Linux环境下段错误的产生原因及调试方法小结
		
转载自http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之 ...
 - 【matlab】MATLAB程序调试方法和过程
		
3.8 MATLAB程序的调试和优化 在MATLAB的程序调试过程中,不仅要求程序能够满足设计者的设计需求,而且还要求程序调试能够优化程序的性能,这样使得程序调试有时比程序设计更为复杂.MATLAB ...
 - 二十四、【开源】EFW框架Winform前端开发之项目结构说明和调试方法
		
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan ...
 
随机推荐
- thinkphp5.0 中使用第三方无命名空间的类库
			
ThinkPHP5建议所有的扩展类库都使用命名空间定义,如果你的类库没有使用命名空间,则不支持自动加载,必须使用Loader::import方法先导入文件后才能使用. 首先要在文件头部使用loader ...
 - 【Docker】利用数据卷容器来备份、恢复、迁移数据卷
			
利用数据卷容器来备份.恢复.迁移数据卷 可以利用数据卷对其中的数据进行进行备份.恢复和迁移. 备份 首先使用 --volumes-from 标记来创建一个加载 dbdata 容器卷的容器,并从主机挂载 ...
 - Converter -> public static int ToInt32(double value) 你用对了么?
			
Convert.ToInt32() 是我们经常使用的方法,但如果我们写如下的代码,能确定它的输出值么? var x = 7.5; Console.WriteLine(7.5 + ": &q ...
 - 什么是Cookie。Cookie的原理介绍,Cookie的简单应用
			
1 介绍:Cookies亦称Cookie .Cookies是一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术.Cookies是当你浏览某网站时,由Web服务 ...
 - 有道单词导入 有道单词 生词本 批量导入 添加  有道单词XML 背单词
			
本程序 主要功能: 对有道生词实现批量导入功能 生成有道单词XML的功能,实现快速导入 有了本程序后就可以批量添加生词. 有道生词本 XML模板 分析 word 为单词,可以为一个单词 ...
 - WCF 之 概述
			
WCF全称是Windows Communication Foundation,它是.NET3.0的重要组成部分,用来解决Windows下的一些通信方面的问题.WCF是Microsoft平台上的SOA架 ...
 - Git学习笔记一--创建版本库、添加文件、提交文件等
			
Git,是Linus花了两周时间用C写的一个分布式版本控制系统.牛该怎么定义? 其实,很多人都不care谁写了Git,只在乎它是免费而且好用的!So do I! 下面开始我们的学习: 1.Git安装( ...
 - iOS APP 上传
			
原地址:http://www.cnblogs.com/uvsjoh/archive/2012/11/14/2769739.html 流程:1 开发好要发布的程序 -- 需要在程序中包含符合要求规格的i ...
 - 为LoadRunner写一个lr_save_float函数
			
LoadRunner中有lr_save_int() 和lr_save_string() 函数,但是没有保存浮点数到变量的lr_save_float函数.<lr_save_float() func ...
 - js中求水仙花数
			
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...