求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
iOS SDK:那些关于iOS调试的技巧
 

发布于2013-6-27

 

为什么你的数组包含3个项目而不是5个?为什么你的游戏运行缓慢?这些都跟调试有关,调试是开发过程中必不可少的一部分。本文所列举了一些重要的调试功能(当然并不全面)可以帮你用更少的时间来解决bug问题。

本文内容主要包括3个方面:

1、使用console检查app状态

2、进行日志记录,并熟练的驾驭NSLog

3、使用对象的生命周期来跟踪内存的使用。

使用Console检查app状态

Xcode底部的小黑盒是我们调试时的好朋友,它可以输出日志信息、错误信息以及其他有用的东西来帮你跟踪错误,除了可以看到日志直接输出的信息外,我们编程过程中也可以在某些断点停留,来检查app的多个方面。

条件断点

我假定你知道Breakpoints是如何工作的(如果你不知道,呵呵,看完这个文章也许你就知道了!)

让程序在某个特定的时间点命中断点非常有价值,但要通过一个循环或者递归函数才能让对象等于某个确定的值,是一件令人痛苦的事情。这时候我们可以使用条件断点!

条件断点就是带有条件表达式的断点,只有满足这个条件,程序才会暂停。假想我们只想在对象处于特定状态的时候断点,或者在第N次迭代循环时命中断点。

点击Xcode editor的‘gutter’来添加断点,右键点击断点,然后选择“edit breakpoint”来设置特定条件。

 

条件断点只有在遇到特定情况时才会中断,你可以提供给一个条件(比如i == 12),或者断点应该忽略的次数。另外,你还可以添加能根据断点自动发生的动作,例如一个debugger command---打印一个值。

提示:添加/删除断点的键盘快捷键是command+\

另外一个重要的断点技巧是添加一个异常断点(exception breakpoint)。当遇到异常时, Xcode基本上都会自动转到main方法的autorelease pool中。

通过设置异常断点,你可以定位到引起异常断点的具体代码行。

如何添加异常断点?

1.打开异常断点tab(command+6);2.选择窗口左下角的”+”按钮;3.选择按钮并添加‘exception breakpoint’。

这样,当Xcode遇到异常情况时,将会在引起异常代码的地方发生断点。

从Console进行手动打印

理论上说,它会展示当前环境中所有值的状态;实际上,有时候会出现bug,并且不会列出值或者当你单步调试的时候不进行更新。

一般情况下,我们在app代码中添加特定断点,是为了通过Xcode提供的‘variables view’(该view在Xcode底部console旁边)来查看对象的状态 。理论上说,它可以显示出与当前上下文相关的所有值的状态。实际上,有时候会有点小问题,不会列出相关的值或者不会进行相关的更新。

不过,我们可以使用一些有用的console命令来检查特定的对象。在console中输入‘po’就可以获得某个断点的即时信息。(处理scalar值时,我们可以使用‘p’)

在我们查看一个已存在的对象时,这一点非常有用(如果对象不存在的话会打印出nil),确定对象的值,找出数组/字典运行时的信息,甚至是比较两个对象。因为这个指令打印出相关对象的内存地址,所以你可以打印你认为应该一样的两个对象,看看它们的内存地址是否相同。

另一个有用的,但是被隐藏的指令是recursiveDescription,你可以简单地用它对view进行检查。

在view中调用recursiveDescription来打印它的继承关系。

有效的Logging

有时,在调试程序的某个特定时间,我们希望将消息打印到控制台,此时‘NSLog’函数允许我们将任意输出打印至console。

此时可以使用NSLog函数,通过该函数可以将任意的输出打印到控制台。在不使用断点时,这个功能非常有用。NSLog遵从的格式与[NSString StringWithFormat]方法遵从的格式一样。(你可以从下边的截图中看到)

Tip: 这里可以看到苹果关于Objective-C中字符串格式化的信息: String Programming Guide

NSLog

NSLog非常有用,我们需要聪明地实现它。从NSLog打印出的任何东西都会变成代码,任何人都可以看见。将设备连接到电脑,打开XCode 中的organiser,就可以从console查看到每条日志信息,这会带来很大的影响。想一下,你想把一些保密的算法逻辑或者用户密码打印到 console。正因为这个,如果苹果发现在production build中,有太多内容输出到console,那么你的应用可能会遭到苹果的拒绝。

幸运的是,这里有一个最简单的办法进行log——通过一个宏,让NSLog只在debug build的时候起作用。将这个功能添加到全局都能访问得到的头文件中。这样你就可以尽情的使用log了,并且当进行production时,不会包含log相关代码。如下代码:

#ifdef DEBUG #define DMLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, 
[NSString stringWithFormat:__VA_ARGS__]) #else #define DMLog(...) do { } while (0)

如果你使用DMLog,那么它只能在debug build期间打印。__PRETTY_FUNCTION__ 也可以帮忙打印出log所在的函数的名称。

下一步

NSLog 很强大,但也有不少限制:

1.只能本地打印

2.不支持分级别的log(比如是危险还是警告)

3.NSLog非常慢,大量处理时会明显降低程序的运行效率。

推荐两个框架,可以避免NSLog一些限制:

Cocoa LumberJack –众所周知的通用的Cocoa日志框架之一,学习起来有点难度,但是非常强大。 SNLog –NSLog的替代品。

跟踪对象的生命周期

尽管Automatic Reference Counting (ARC)已经让内存管理变得简单、省时和高效,但是在object的life-cycles中跟踪一些重要事件依然十分重要。毕竟ARC并没有完全排除 内存泄露的可能性,或者试图访问一个被release的对象。为了这个目的,我们可以用一些处理方法和工具来帮助我们盯着对象正在做些什么。

LOG重要事件

Objective-C 对象的 life-cycle中有两个很重要的方法: init 和dealloc ,将这两个方法调用的事件log到console是不错的选择——你可以通过控制台观察到对象生命的开始,更重要的是,可以确保对象的释放。

静态分析器和Inspector(检查器)

Xcode中还有两个工具可以帮我们清理代码,减少代码出错的几率。对Xcode而言,静态分析器工具是一个非常棒用来改善代码的工具。比如检 测出没有使用过的对象,没有release对象(针对Core Foundation对象,ARC仍然会有这样的问题)。通过选择Product菜单中的‘Anlayze’可以查看到相关建议。

检查器是非常强大的一组工具,通过检查器不仅可以从不同的角度检查程序对内存的使用情况,文件系统的使用情况(增加、删除、修改等),甚至还提供了自动UI交互的方法。通过选择Product菜单中的‘Profile’可以查看到这些检查器。

选择‘Profile’会打开一个Instrument窗口,这里可以选择一个配置模板进行运行。最常用的模板有zombies(稍后会讨论),activity monitor和leaks。在程序运行时,对内存泄露进行捕捉时,Leaks可能是最有用的一个模板。

Zombies是你的朋友

虽然在有ARC的地方很难再遇到让人难受的EXC_BAD_ACCESS错误了,但是在某些确定的情况下,该错误还是会发生的。当在处理 UIPopoverController或者core foundation对象时,我们可以访问一个已经被release掉的对象。一般,当我们release内存中的一个对象时,该对象将被销毁。但是,当 Zombies开启时,只是将对象标记为release,实际上该对象还停留在内存中。当我们访问一个Zombie对象时,Xcode可以告诉我们正在访 问的对象是一个不应该存在的对象了。因为Xcode知道这个对象是什么,所以可以让我们知道这个对象在哪里,以及这是什么时候发生的。

这里有两种方法可以查找出Zombies对象。使用检查器中的Zombie配置模板,或者在‘Run’ build选项中开启Zombie诊断选项。在Stop按钮的旁边,点击scheme名称,然后选择‘Edit Scheme’,点击diagnostic tab项,并勾选上‘Enable Zombie Objects’。注意,Zombie只能用在模拟器调试中,真机上不能使用。

注意,Zombie模式调试仅适用于模拟器,不能在真实设备上使用。

总结

希望以上内容能给你帮你更高效地调试你的app,所有这些都是为了能都节省bug修复时间,这样开发者就能把时间花在更重要的事情上,或者打造一款伟大的应用程序。

上边列出的肯定不是一个全面的列表,还有很多我们没有讨论的方法,比如远程遥控bug报告,崩溃报告以及更多。也希望你能分享更多。

相关文章

微服务测试之单元测试
一篇图文带你了解白盒测试用例设计方法
全面的质量保障体系之回归测试策略
人工智能自动化测试探索
相关文档

自动化接口测试实践之路
jenkins持续集成测试
性能测试诊断分析与优化
性能测试实例
相关课程

持续集成测试最佳实践
自动化测试体系建设与最佳实践
测试架构的构建与应用实践
DevOps时代的测试技术与最佳实践
 
分享到
 
 
     


LoadRunner性能测试基础
软件测试结果分析和质量报告
面向对象软件测试技术研究
设计测试用例的四条原则
功能测试中故障模型的建立
性能测试综述
更多...   


性能测试方法与技术
测试过程与团队管理
LoadRunner进行性能测试
WEB应用的软件测试
手机软件测试
白盒测试方法与技术


某博彩行业 数据库自动化测试
IT服务商 Web安全测试
IT服务商 自动化测试框架
海航股份 单元测试、重构
测试需求分析与测试用例分析
互联网web测试方法与实践
基于Selenium的Web自动化测试
更多...