为Objective-C编程调试技巧(译)

http://www.cocoawithlove.com/2008/10/debugging-tips-for-objective-c.html

这篇文章是关于从程序获得额外的信息在运行时。Xcode和GDB都支持广泛的信息获取工具 - 但你需要知道,他们在那里。下面是一些Objective-C的具体gdb的提示和指令,所有的Cocoa程序员应该知道的。

说话直接用gdb

调试器控制台窗口很聊得来的gdb的方式。从运行菜单(或type命令移-R)显示在Xcode的控制台窗口。

您只能发送命令到GDB当程序暂停(停止在断点处)。当你有(GDB)提示,然后你可以跟gdb调试程序。

大多数命令,gdb的接受,Xcode的通过显示在调试器窗口中的值会自动为你处理。所以我打算忽略其中的大多数。

"po":打印对象

打印对象命令显示一个Objective-C的对象的文本表示。

想象一下,你想知道为什么你的电话:

- (ID )getFirstObjectFrom:(NSDictionary中 *)stringDictionary
{
    返回 [stringDictionary objectForKey @“FIRSTKEY” ];
}

将返回零。设置就行了断点,当调试器停止在这一点上,进入调试器控制台,然后键入:

po   stringDictionary

命中回报和gdb会给出结果。就我而言,它是:

{
    FIRSTKEY = firstObject;
    secondKey = secondObject;
    thirdKey = thirdObject;
}

我应该使用的键名是@“FIRSTKEY”以小写'F'。问题解决了。

在这种情况下,gdb的被调用描述的方法的NSDictionary生成的字符串。该描述方法用于所有的整个可可来生成对象的字符串,你可以重写它,以提供您的对象的字符串表示形式。

Xcode的数据格式化

如果调试器仍然停在同一条线上,你在Xcode打开调试器窗口,变量的“参数”列表将包含一个条目stringDictionary。对于一个的NSDictionary这样的对象,Xcode中会显示在“摘要”栏“3键/值对。”

此信息来自一个“数据格式化”,也就是设立的NSDictionary默认。你可以了解他们在苹果的Xcode调试指南:使用数据格式化。从本质上讲,数据格式化告诉Xcode中如何获取一些数据在列中显示。

不同的数据格式可以看出,如果我们在右键单击stringDictionary行中的调试器窗口,然后从上下文菜单中选择“打印说明以控制台”。

打印 的说明 stringDictionary
< CFDictionary 0 x 3 5 EDD 0 [ 0 XA 0 b 0 6 1 7 4 ]> {类型=不变,计数= 3 ,容量= 3 ,对=(
    0 :< CFString字符串 0 x 2 0 9 0 [ 0 XA 0 b 0 6 1 7 4 ]> {内容=“secondKey”} = < CFString字符串 0 x 2 0 8 0 [ 0 XA 0 b 0 6 1 7 4 ]> {内容=“secondObject”}
    1 :< CFString字符串 0 x 2 0 b 0 [ 0 XA 0 b 0 6 1 7 4 ]> {内容=“thirdKey”} = < CFString字符串 0 x 2 0 0 [ 0 XA 0 b 0 6 1 7 4 ]> {内容=“thirdObject”}
    3 :< CFString字符串 0 x 2 0 7 0 [ 0 XA 0 b 0 6 1 7 4 ]> {内容=“FIRSTKEY”} = < CFString字符串 0 x 2 0 6 0 [ 0 XA 0 b 0 6 1 7 4 ]> {内容=“firstObject”}
)}

如果没有数据格式,“打印说明以控制台”将输出相同的信息为“宝”命令。在这种情况下,虽然,它清楚地输出一个更详细的描述的字典,具有完整的类型信息和索引。正是这个CFDictionary数据格式化驻留是未知的我(它不是在为Xcode中的数据格式化的标准位置)。

其他的“打印”命令

该PO在gdb的命令永远只能显示结果从调用描述一个物体上,但更普遍的打印命令将让我们做其他事情。

我可以使用下面的命令:

打印(字符*)[[stringDictionary 描述] 的CString ]

这将有输出:

$ 1 = 0 x 3 6 0 0 3 1 “{\ñFIRSTKEY = firstObject; \ñsecondKey = secondObject; \ n
    thirdKey = thirdObject; \ n}的“

这是相同的数据表示为宝为例,减去漂亮的格式。

我还可以使用下面的命令:

打印(整型)[stringDictionary retainCount ]

制定出的保留计数stringDictionary帮我工作了,为什么内存或者是没有得到释放。

由于与PO命令和“打印说明以控制台”在Xcode相等,则打印命令有一个Xcode的等价了。您可以从运行- >显示- >表达式菜单打开表达式窗口。

“信息符号”:得到一个地址的符号名

最后的gdb命令我要在这里讨论的是信息符号的地址,返回与给定的存储单元关联的任何变量或代码的名称地址

想象一下,例如,你的内存地址“混淆0xa0b06174通过“打印说明到控制台”输出显示“stringDictionary那我上面显示。所有您需要做的则是类型:

信息符号0 XA 0 b 0 6 1 7 4

进入调试器控制台和gdb会告诉你:

__kCFAllocatorSystemDefault 部分LC_SEGMENT 。__DATA 。__data 的/系统/库/框架/的CoreFoundation 。框架/版本/ A /的CoreFoundation

这是系统默认的CoreFoundation内存分配器。也许这还并不意味着一大堆,但至少我们知道在该地址中声明的对象的名称。

当你得到一个异常日志,看起来像这样更加有用的是:

2 0 0 8 - 1 0 - 2 6 13 2 5 4 3 .381 CrashExample [ 4 1 7 2 0 2 0 B] *** - [ TransitionView doesntExist ]:无法识别的选择发送到实例0 XF 4 FBB 0
2 0 0 8 - 1 0 - 2 6 13 2 5 4 3 0.383 CrashExample [ 4 1 7 2 0 2 0 B] *** 终止 应用程序因未捕获的异常'NSInvalidArgumentException', 原因:'*** - [ TransitionView doesntExist ]:无法识别的选择发送到实例0 XF 4 FBB 0 '
2 0 0 8 - 1 0 - 2 6 13 2 5 4 3 .385 CrashExample [ 4 1 7 2 0 2 0 B] 堆栈:(
    2 5 2 8 0 1 3 8 0 4
    2 4 7 8 5 0 3 1 4 8
    2 5 2 8 0 4 2 9 2 0
    2 5 2 8 0 3 6 2 7 2
    2 5 2 8 0 3 6 9 2 0
    1 1 0 7 6
    1 1 8 8 0
    8 1 6 1 7 4 8 8 0
    8 1 6 1 7 4 8 8 0
    8 1 6 5 0 4 0 3 6
    8 1 6 5 0 0 9 6 0
    8 1 6 2 5 8 7 9 2
    8 1 6 2 0 2 1 2 8
    8 1 6 1 9 9 5 0 8
    8 2 9 0 0 5 5 2 0
    8 2 9 0 1 4 7 7 2
    2 5 2 7 5 6 4 4 5 6
    8 2 9 0 0 7 7 2 4
    8 1 6 1 7 3 0 1 6
    8 1 6 2 1 2 3 3 6
    9 8 8 8
    9 6 6 8

日志告诉我们发生了,因为一个无法识别的选择发送到一个对象,但我们可能不知道在这个程序中发生的问题。

你可以看一下堆栈跟踪,看到的最高地址是“小”(即可能是在你的代码,而不是默认的库)为“11076”,然后给gdb的命令:

信息符号1 1 0 7 6

和gdb会告诉你:

- [ CrashExampleAppDelegate performTransition ] + 8 8 部分LC_SEGMENT 。__TEXT 。__text 的/用户/哑光/项目/ CrashExample 。应用程序/ CrashExample

它告诉我们,这个问题发生在方法performTransition。

更新:由于在评论中指出的“G”,还有一个更好的方法来确定的方法和代码行的在这种情况下一个地址。信息行* 11076会以原始的源代码文件中的行,而不仅仅是字节从函数的起始偏移量。

这使得它烦人,在Mac OS X 10.5 -如果你看看5上面的地址列表中的11076,他们都与抛出异常本身相关联objc_exception_throw只返回前5名地址,因为这5个地址往往是相同的异常抛出地址(他们不说任何事情,为什么抛出异常)。

地址和符号调试器外

既然我提到坠毁阅读文件和查看内存地址:GDB不这样做,如果最好的方法别人给你的内存地址。要做到这一点,你应该从他们所使用的确切构建有。的dSYM文件。

如果你不知道如何生成。的dSYM文件,转到项目 - >编辑项目设置 - >生成 - >生成选项 - >调试信息格式,并确保你有一个的dSYM文件。你应该保留这些文件大约为每个建立你释放。iPhone SDK的默认生成这些文件,但您将需要打开的手动上为Mac版本。

调用的命令行如下:

dwarfdump-A的<em> NameOfdSYMFile </ em>的

这会告诉你该文件中的每一知道地址。所有您需要做的是找到最接近上述任一地址到您崩溃的位置,这将是罪魁祸首方法或函数。

然而,这是一个非常笨拙的方法。为了得到一次单一的地址,将。的dSYM和。的应用程序,它是指在同一目录下,你可以使用ATOS命令可以获得一个地址一个符号。上面显示的CrashExample崩溃的bug,你可以调用这个命令是这样的:

ATOS-O CrashExample 。应用程序/内容/的MacOS / CrashExample 拱PPC 1 1 0 7 6

这将使结果:

- [ CrashExampleAppDelegate performTransition ]( CrashExample)(CrashExampleAppDelegate 。米9 4

最后,如果你想从一个崩溃日志得到所有的地址,你可以使用苹果的symbolizecrashlog脚本。这一发现的。应用程序和。的dSYM文件为。的Crash.log文件,并调用ATOS得到遏制。内的每一个可能的符号感谢millenomi指出这一点的意见。

结论

有很多详细信息,在调试的时候挤出不仅仅是在你的变量的原始值。有机会获得这些信息,在调试过程中,可以跟踪Bug,只是有点快。

Objective-C编程调试技巧的更多相关文章

  1. java编程调试技巧

    1 多线程调试 开发过多线程应用的朋友应该有体会,有些时候,为了观察多个线程间变量的不同状态,以及锁的获取等,就会想到在代码里加个断点debug一下. 在IDE里断点停下来的时候,可以切换到另外的线程 ...

  2. shell编程学习笔记【原创】

    本文为本人学习笔记,如有转载请注明出处,谢谢 一.Bourne Shell 有如下四种变量: 用户自定义变量 位置变量,即命令行参数 预定义变量 环境变量 二.位置变量 $ 与键入的命令行一样,包含脚 ...

  3. Automake

    Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...

  4. [No00007F]2016-面经[下] 英文简历写作技巧

    一.简历种类 1.中式 中式简历中,常包括政治面貌,性格及身高体重等.如果中英文简历一起递交,建议中文不写政治面貌,因为如果去外企工作,背景中的政治色彩越少越好,起码没有必要让老外知道. 性格是一个主 ...

  5. iOS开发——开发技巧&LLDB详解

    开胃小菜--简单的断点调试 在xcode中打开一个app,在想要break的行号上单击,即可生成一个深色的箭头标识--断点.如下图,在viewDidLoad:中设置了断点. 运行app,等待...就可 ...

  6. KVC技巧二则

    说两个与KVC相关的技巧. 1.KVC与字典 有时候我们需要取出嵌套字典中的某个键的值.例如某个嵌套字典: NSDictionary *dict = @{@"subDict":@{ ...

  7. C#中??和?分别是什么意思? 在ASP.NET开发中一些单词的标准缩写 C#SESSION丢失问题的解决办法 在C#中INTERFACE与ABSTRACT CLASS的区别 SQL命令语句小技巧 JQUERY判断CHECKBOX是否选中三种方法 JS中!=、==、!==、===的用法和区别 在对象比较中,对象相等和对象一致分别指的是什么?

    C#中??和?分别是什么意思? 在C#中??和?分别是什么意思? 1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; ...

  8. iOS开发核心语言Objective C —— 全部知识点总结

    本分享是面向有意向从事iOS开发的伙伴及苹果产品的发烧友,亦或是已经从事了iOS的开发人员,想进一步提升者.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基 ...

  9. PHP、 Ruby、Python、Java、C++、C、Objective C——编程语言之禅

    PHP是你豆蔻年华时的心上人,她是情窦初开的你今年夏天傻乎乎追求的目标.玩一玩可以,但千万不要投入过深,因为这个“女孩”有严重的问题. Ruby是脚本家族中一个非常漂亮的孩子.第一眼看她,你的心魄就会 ...

随机推荐

  1. Python中各种集合 list tuple set dict

    list 创建list        L = ['Adam','Lucy','Bart'] 索引访问:  正序(和数组类似)     L[0],L[1],L[2] 倒序 L[-1]倒数第一个  L[- ...

  2. 读<<代码整洁之道>>的感想

    花去了近一周的时间浏览一下这本书.总体感觉这本书写得不错. 我发现自己以前写的代码时多么的糟糕.有很多改进之处... 同时我也发现写出优秀的代码不易.优秀的代码不仅仅易读,并且易修改,易维护,程序易维 ...

  3. Wikioi 1294 全排列

    先给出链接地址:Wikioi 1294 虽然题目很短,论难度也就是个深搜,算法方面我就不多说了,而且我知道c++有个函数叫next_permutation,谁用谁知道. 代码如下: #include& ...

  4. 借贷宝推广得现金是真的_注册就送人民币20元_邀请码CRJYQTK

    动动手指,20元立即到手.即优步uber打车和滴滴专车豪投数亿元争夺专车市场之后,一款名为借贷宝的APP推广在网上流传开来,目前主要看重的就是它的推广力度,豪投20亿让大众来推广.简单流程:下载借贷宝 ...

  5. GCC 编译选项

    http://www.cnblogs.com/xmphoenix/archive/2011/03/21/1989944.html GCC 编译选项(转) gcc提供了大量的警告选项,对代码中可能存在的 ...

  6. SQLite.dll混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。

    其他信息: V5.7.4.4 Can't find the System.Data.SQLite.dll more info : 混合模式程序集是针对"v2.0.50727"版的运 ...

  7. Android EditText限制输入一些固定字符的属性

    android:digits="abcdefghijklmnopqrstuvwxyz1234567890" 仅仅能输入这些

  8. UVA11387 - The 3-Regular Graph(推理)

    题目链接 题意:给n个点,问能否画出一个无向图.且每一个顶点连接3条边.假设能够的话输出连接的边. 思路:当添加一条边时,总的无向图的度数会添加2,所以度数之和n*2为偶数.当n为奇数时,度数之和为奇 ...

  9. 纯CSS3编写的面包屑导航收集

    整理了10个纯CSS3制作的面包屑导航,这些都是通过CSS3来编写,十分方便,而且实用.有些文章附有教程,大家可以研究学习一下. 漂亮面包屑导航 查看网站 扁平化面包屑导航 查看网站 圆形风格面包屑导 ...

  10. oracle后台进程2

    oracle中的进程共分为三类:用户进程.服务进程.后台进程.其中后台进程伴随实例的启动而启动,他们主要是维护数据库的稳定,相当于一个企业中的管理者及内部服务人员.他们并不会直接给用户提供服务. 一: ...