iOS开发——调试篇&Xcode常用调试技巧

Xcode常用调试技巧


Enable NSZombie Objects(开启僵尸对象)

Enable NSZombie Objects可能是整个Xcode开发环境中最有用的调试技巧。这个技巧非常非常容易追踪到重复释放的问题。该技巧会以非常简洁的方式打印指出重复释放的类和该类的内存地址。

怎么开启僵尸对象呢?首先打开“Edit Scheme”(或者通过热键?<),然后选择Diagnostics选项卡,勾选Enable NSZombie Objects选项。

现在我们可以关掉ARC来测试重复释放的问题、异常和更容易产生的Crashs,但是即使开启ARC,重复释放和与内存相关的Crashs也经常发生。现在假设我们犯了一些错误导致了重复释放的发生来观察将要发生什么。

1 UIView* view = [[[UIView alloc] init] autorelease];
2 //...
3 //do something with view...clearly forgetting that it has been autoreleased.
4 //
5 [view release];   

现在运行这段代码会发生重复释放的问题,程序将崩溃在主函数,会像下面这样:

Enable NSZombie Objects会让调试器看起来像这样:

这个例子看起来作用非常小,但是对于一个大工程通过Enable NSZombie Objects打印的信息是非常有用的。


对于所有异常添加Global BreakPoint(全局断点)

当 你的应用异常或者崩溃的时候Xcode喜欢做的一件事情是直接跳到主函数,就像第一个调试技巧中用到的那个例子一样。如果异常或者崩溃能够停 留在异常或者崩溃发生的地方那该是多好呀。幸运的是有一个方法可以做到。Xcode有一个漂亮的功能叫做异常断点,允许我们在异常发生的时候在异常发生的 地方放一个断点。你可以指定具体的异常也可以指定所有的异常。

怎样开启异常断点呢?工程切换到异常浏览窗口,点击下方左侧的“Add Breakpoint”按钮,然后选择“Add Exception Breakpoint”确保可以捕获所有异常。

现在异常发生时调试器不会直接跳转到主函数了,而是停留在了异常发生的地方。

这个断点给了我们一个调试异常非常好的开始的点,不用我们再去遍历代买去找异常发生的地方了。


Static Analyzer(静态分析)

Static Analyzer是一个非常好的工具去发现编译器警告不会提示的问题和一些个人的内错泄露和死存储(不会用到的赋了值的变量)错误。这个方法可能大大的提高内存使用和性能,以及提升应用的整体稳定性和代码质量。

怎么打开Static Analyzer?打开Xcide的“Product”菜单,选择Analyzer选项(或者使用热键? shift B)。正像你看到的下面的截图,Static Analyzer会捕获任何应用内的可能的问题然后以蓝色的警告展示出来。

我们也可以设置我们的应用在我们编译应用的时候自动开启Static Analyzer,打开项目project文件,设置“Run Static Analyzer”为YES,如下图:


 Condational Breakpoints(条件断点)

最后一个调试技巧条件断点,这只是普通的断点,当变量满足一定条件时程序停止。这个调试技巧在当你想要捕获一个循环中的变量的特定值或者一些不常发生的情况时是非常有用的,而不用你每次迭代都停止来查看。

怎样开启条件变量?只不过是添加一个普通断点,然后右键点击断点选择“Edit Breakpoint”,这时就打开了一个断点编辑器,你可以在这里设置断点条件(以及一些其他的断点设置),然后选择“Done”,这个调试技巧非常简单吧。


重写object的respondsToSelector方法

在iphone开发的时候EXC_BAD_ACCESS这个bug时不容易找到原因的。

首先说一下EXC_BAD_ACCESS 这个错误,可以这么说,90%的错误来源在于对一个已经释放的对象进行release操作,或者操作一个在循环代码中被修改的序列中的对象。虽然使用NSZombieEnabled变量可以帮助你找到问题所在,但有的时候,即使通过设置NSZombieEnabled变量,还是不能定位到问题所在,这个时候,你可以试试重写object的respondsToSelector方法,显示出现EXEC_BAD_ACCESS前访问的最后一个object,下面是具体的步骤:

a、在每个类并且在 other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。的实现文件(.m,.mm)文件中,添加如下代码:

-(BOOL) respondsToSelector : (SEL)aSelector {
    printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
    return [super respondsToSelector:aSelector];
}

b、并且在 other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。


让XCode反馈足够多的信息

在Edit–>Scheme里面 找到Arguments ,在Environment Variables这里添加
把下面2个值设置成YES
NSAutoreleaseFreedObjectCheckEnabled
NSDebugEnabled
这种方法非常好用,建议在建立一个工程的时候,加入此设置


unrecognized selector send to instancd 快速定位

在Debug菜单中Breakpoints->Create Symbolic Breakpoint

在Symbolic中填写如下方法签名

  1. -[NSObject(NSObject) doesNotRecognizeSelector:]

设置完成后再遇到类似的错误就会定位到具体的代码。

你也可以这样做,在系统抛出异常处设置断点:和上面的含义一样

程序不知道跑到哪个地方就 crash 了,而 crash 又很难重现。

保守的做法是: 在系统抛出异常之前设置断点. (具体来说是在 objc_exception_throw 处设置断点。)

设置步骤为:

1. 在 XCode 按 CMD + 6,进入断点管理窗口;
2. 然后点击右下方的 +,增加新的 Symbolic Breakpoint。
3. 在 Symbol 一栏输入:objc_exception_throw,然后点击 done,完成。


高级装逼技术-GDB

XCode 内置GDB,我们可以在命令行中使用 GDB 命令来调试我们的程序。下面将介绍一些常用的命令以及调试技巧。

po 命令:为 print object 的缩写,显示对象的文本描述(显示从对象的 description 消息获得的字符串信息)。

比如:


上图中,我使用 po 命令显示一个 NSDictionary 的内容。注意在左侧我们可以看到 dict 的一些信息:3 key/value
pairs,显示该 dict 包含的数据量,而展开的信息显示 isa 层次体系(即class 和
metaclass结构关系)。我们可以右击左侧的 dict,选中“Print Description of "dict"”,则可以在控制台输出
dict 的详细信息:

Printing description of dict:  

{type = immutable dict, count = 3,  

entries =>  

    0 : {contents = "first"} = {contents = "one"}  

    1 : {contents = "second"} = {contents = "two"}  

    2 : {contents = "third"} = {contents = "three"}  

}  

print 命令:有点类似于格式化输出,可以输出对象的不同信息:

如:

(gdb) print (char *)[[dict description] cStringUsingEncoding:4]

  • $1 = 0x1001159c0 "{\n    first = one;\n    second = two;\n    third = three;\n}"

(gdb) print (int)[dict retainCount]

  • $2 = 1

(gdb)

注:4是 NSUTF8StringEncoding 的值。

info 命令:我们可以查看内存地址所在信息

比如 "info symbol 内存地址" 可以获取内存地址所在的 symbol 相关信息:

(gdb) info symbol 0x00000001000017f7

  • main
    + 343 in section LC_SEGMENT.__TEXT.__text of
    /Users/LuoZhaohui/Library/Developer/Xcode/DerivedData/RunTimeSystem-anzdlhiwvlbizpfureuvenvmatnp/Build/Products/Debug/RunTimeSystem

比如 "info line *内存地址" 可以获取内存地址所在的代码行相关信息:

(gdb) info line *0x00000001000017f7

  • Line
    62 of
    "/Users/LuoZhaohui/Documents/Study/RunTimeSystem/RunTimeSystem/main.m"
    starts at address 0x1000017f7 and ends at 0x10000180a .

show 命令:显示 GDB 相关的信息。如:show version 显示GDB版本信息

(gdb) show version

  • GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug  8 20:32:45 UTC 2011)
  • Copyright 2004 Free Software Foundation, Inc.
  • GDB is free software, covered by the GNU General Public License, and you are
  • welcome to change it and/or distribute copies of it under certain conditions.
  • Type "show copying" to see the conditions.
  • There is absolutely no warranty for GDB.  Type "show warranty" for details.
  • This GDB was configured as "x86_64-apple-darwin".

help 命令:如果忘记某条命令的语法了,可以使用 help 命令名 来获取帮助信息。如:help info 显示 info 命令的用法。

(gdb) help info

  • Generic command for showing things about the program being debugged.
  • List of info subcommands:
  • info address -- Describe where symbol SYM is stored
  • info all-registers -- List of all registers and their contents
  • info args -- Argument variables of current stack frame
  • info auxv -- Display the inferior‘s auxiliary vector
  • info breakpoints -- Status of user-settable breakpoints
  • info catch -- Exceptions that can be caught in the current stack frame
  • info checkpoints -- Help
  • info classes -- All Objective-C classes
  • ......
  • Type "help info" followed by info subcommand name for full documentation.
  • Command name abbreviations are allowed if unambiguous.

常见GDB命令

        • break NUM               在指定的行上设置断点。
        • bt                      显示所有的调用栈帧。该命令可用来显示函数的调用顺序。
        • clear                   删除设置在特定源文件、特定行上的断点。其用法为:clear FILENAME:NUM。
        • continue                继续执行正在调试的程序。该命令用在程序由于处理信号或断点而导致停止运行时。
        • display EXPR            每次程序停止后显示表达式的值。表达式由程序定义的变量组成。
        • file FILE               装载指定的可执行文件进行调试。
        • help NAME               显示指定命令的帮助信息。
        • info break              显示当前断点清单,包括到达断点处的次数等。
        • info files              显示被调试文件的详细信息。
        • info func               显示所有的函数名称。
        • info local              显示当函数中的局部变量信息。
        • info prog               显示被调试程序的执行状态。
        • info var                显示所有的全局和静态变量名称。
        • kill                    终止正被调试的程序。
        • list                    显示源代码段。
        • make                    在不退出 gdb 的情况下运行 make 工具。
        • next                    在不单步执行进入其他函数的情况下,向前执行一行源代码。
        • print EXPR              显示表达式 EXPR 的值。
        • print-object            打印一个对象
        • print (int) name      打印一个类型
        • print-object [artist description]   调用一个函数
        • set artist = @”test”    设置变量值
        • expr gestureDisabled = 1  设置变量值
        • whatis                  查看变理的数据类型
时间: 2024-10-24 17:18:05

iOS开发——调试篇&Xcode常用调试技巧的相关文章

iOS开发数据库篇—SQLite常用的函数

iOS开发数据库篇—SQLite常用的函数 一.简单说明 1.打开数据库 int sqlite3_open( const char *filename,   // 数据库的文件路径 sqlite3 **ppDb          // 数据库实例 ); 2.执行任何SQL语句 int sqlite3_exec( sqlite3*,                                  // 一个打开的数据库实例 const char *sql,                    

iOS开发——实战篇&amp;Xcode 7真机测试详解

Xcode 7真机测试详解 1.准备 注意:一定要让你的真机设备的系统版本和app的系统版本想对应,如果不对应就会出现一个很常见的问题:could not find developer disk image 首先,准备好下面的设备机相关软件 MAC版本:OSX10.10.4 Xcode版本:Xcode7 beta5(点击下载) 真机设备:iPad Air(iOS 8.1.3)/iphone 6 2.首先先安装Xcode7,并且运行Xcode,点击左上角菜单Xcode -> Preferences

IOS开发数据库篇--- &quot;sqlite常用语句&quot;

/*简单约束*/ CREATE TABLE IF NOT EXISTS t_student(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER); CREATE TABLE IF NOT EXISTS t_student(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER NOT NULL); CREATE TABLE IF NOT EXI

文顶顶 iOS开发UI篇—IOS开发中Xcode的一些使用技巧

iOS开发UI篇—IOS开发中Xcode的一些使用技巧 一.快捷键的使用 经常用到的快捷键如下: 新建 shift + cmd + n     新建项目 cmd + n             新建文件 视图 option + cmd + 回车 打开助理编辑器 cmd + 回车           显示主窗口 cmd + 0             导航窗口 option + cmd + 0    工具窗口 在.m & .h之间切换           control + cmd + 上/下 按

iOS开发:创建真机调试证书

iOS开发:创建真机调试证书 工具/原料 能上网的苹果电脑 浏览器 Xcode 5.1.1以上 苹果开发者账号 ITunes软件 iOS设备(iPhone.ipad均可) 方法/步骤 1 首先打开苹果的开发者网站(Tips:这里我就不贴网址了) 点击网站上方的Member Center,会跳转到登录界面(Tips:如果登录过,并选择了浏览器保存此密码的时候,默认是登录状态). 2 如图所示输入你的开发者账号和密码. 输入完成后点击"Login"(Tips:左边是注册,下边是找回密码,右

iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)

iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接) 这里推荐两款好用的Xcode插件,并提供下载链接. 一.插件和使用如下: 1.两款插件 对项目中图片提供自动提示功能的插件:KSImageNamed-Xcode-master 提供快速创建自动注释:VVDocumenter-Xcode-master 2.使用介绍: (1)KSImageNamed-Xcode-master的使用 安装该插件后,会对文件中图片进行智能提示. (2)VVDocumenter-Xcode-master能提供

iOS开发UI篇—常见的项目文件介绍

iOS开发UI篇—常见的项目文件介绍 一.项目文件结构示意图 二.文件介绍 1.products文件夹:主要用于mac电脑开发的可执行文件,ios开发用不到这个文件 2.frameworks文件夹主要用来放依赖的框架 3.test文件夹是用来做单元测试的 4.常用的文件夹(项目名称文件夹) (1)XXXinfo.plist文件(在该项目中为  01-常见文件-Info.plist) 1)简单说明 是配置文件,该文件对工程做一些运行期的配置,非常重要,不能删除. 在旧版本xcode创建的工程中,这

iOS开发UI篇—常见的项目文件介绍 - 文顶顶

原文  http://www.cnblogs.com/wendingding/p/3766249.html iOS开发UI篇—常见的项目文件介绍 一.项目文件结构示意图 二.文件介绍 1.products文件夹:主要用于mac电脑开发的可执行文件,ios开发用不到这个文件 2.frameworks文件夹主要用来放依赖的框架 3.test文件夹是用来做单元测试的 4.常用的文件夹(项目名称文件夹) (1)XXXinfo.plist文件(在该项目中为  01-常见文件-Info.plist) 1)简

iOS开发-Swift篇-(1)

iOS开发Swift篇—简单介绍 一.简介 Swift是苹果于2014年WWDC(苹果开发者大会)发布的全新编程语言 Swift在天朝译为“雨燕”,是它的LOGO 是一只燕子,跟Objective-C一样,可以用于开发iOS.Mac应用程序 苹果从2010年7月开始设计Swift语言,耗时4年打造 Swift的语法特点 从它的语法中能看到Objective-C.JavaScript.Python等语言的影子 语法简单.代码简洁.使用方便 可与Objective-C混合使用(相互调用) 为什么要设