OC编写使用调试器

编写代码免不了,Bug。那么Debug就是程序员的必备技能了。本文和大家一起探讨,如何在应用开发编写代码过程中,使用日志项消息;以及使用动作、条件、迭代控制增强断点。

  1. 记录信息

    在需要与应用的终端用户进行沟通是可以使用Cocoa和Cocoa Touch框架提供的各种各样的工具来完成。本文是学习开发过程中用来与自身以及合作者进行沟通的小心得,小体会。

    与小伙伴们进行沟通可以使用日志消息赖在代码中进行注释,这样其他开发该项目的人员也就能够了解代码的真实意图,一般来讲,大家都同意多代码进行注释,但是若使用日志的话,用户就能够在一个窗口中运行该程序并在另一个窗口中查看日志信息。日志消息(即使它们与代码中的注释是完全一样的)能够提供一个可以运行的注释。

    • 控制台日志——开发员可以像大多数语言中所做的那样向控制台输出日志。
    • 断点——可以在代码中插入断点,当代码的执行到断点处停止后,当前变量以及其值会被显示出来。

      2.使用控制台日志

      在/Applications/Utilities文件夹中包含了一个名为Console的应用。细心的开发者会注意到使用系统日志工具在硬盘根目录下/Library/Logs/或者/library/Logs/下生成的日志项,至于日志项到底存放哪个目录下列则需要依赖于日志的性质。Consonle能够查看所有这些日志,至于日志项到底窗口的左边,每一项日志都会自动,加上时间戳。从窗口的右上角可以看出,可以对日志进行搜索。

      由于系统软件会不断地更新各种日志,因此读者可以自己启动Console来查看日志项。

      3.使用NSLog

      可以使用Foundation中的函数NSLog来生日志项。各个日志项左边的时间戳和进程ID是由NSLog自动生成的。下面是NSLog的语法。
void NSLog {
NSString *format;
...
};
注意NSLog接收的参数数量是可变的。实际上,它会将所有参数组合起来并调用NSLogv函数,该函数会接收两个参数——NSSSring格式参数和一个可变参数列表(va_list),但是实际使用时,开发人员无须关心NSLogv。
这里比较重要的一点是format参数(NSString)是一个标准的C格式字符串,虽然NSLog函数已经对该参数进行了扩展。下面一个典型的NSLog调用
```
NSLog (@"Finished conversion routine with result %d",myResult);
```
格式字符串包含了一串常规信息字符串,后面跟着一个表示整数的标准的C格式字符串(%d)。

增强NSLog

在C的预处理器中内置了一些宏和表达式,它们对于日志记录非常有用的。给出了C语言(Objective-C,C和C++)中的宏(注意在表中宏的名称以两个下划线字符开头和结尾)。

格式 描述
func %s 函数签
LINK %d 当前代码的行数
EILE %s 当前代码的文件名
PRETTY_FUNCTION %S fun类似,但在C++中该宏提供更多信息

Objective-C中日志表达式

格式 描述
NSstringFromSelector %@ 当前的选择器(注意_cmd只有一个下划线)
NSStringFromClass([self class]) %@ 当前代码行数
[NSstringstringWithUTF8String:] %@ 源代码的文件名
FILE]lastPathComponnet
NSThreadclallStackSymbols %@ 存放在NSArray中当前栈轨迹

通过上面的宏定义和表达式能够创建像下面这样的SLOG宏定义,该宏定义是基于developerr.apple.com站点上,Simple Scripting 示例的,它封装了对NSLog的调用,并且用到了上述表中的一些宏。在调用SLOG宏时需要传入格式字符串,并且通过文件名/行数以及函数签名会被自动添加到日志项中。

4.使用智能断点

只需在Xcode编辑器中响应的代码行上点击槽装的图标即可。值得一提的是定制断点消息非常有用,简单的来说修改断点使其位于一个循环几次的循环中。完成这一任务最简单的方式是使用Code Snippet库:将for语句拖到代码中,

    -(void) applicationDidFinishLauching:(NSNotification *)aNotification
{
for (int counter=1;count<10;count++)
{
NSNumber *myFactor=[NSNumber numberWithFloat:8];
NSNumber *myUnits = [NSNumber numberWithFloat:5];
converter = [[Converter alloc] initWithFactor:myFator];
NSNumber *result =[[converter units: myUnits]];
}
}

将断点移动到循环中(不管放在循环体什么位置),确保在断点处会项之前那样记录一条消息,但这里需要选上Option复选框使它自动往下执行。在完成这些修改之后点击Done。

在Xode中再次运行该应用并查看结果。由于应用在执行完断点处的动作之后会继续往下执行,因此调试器不会弹出来,消息会被写入到控制台中,但如果打开了调制器之后,(或使用Utilities文件夹下的console应用)就能看到所有动作消息。

修改断点使之在count>5时触发并再次运行应用。

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

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



analyse

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

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

5.带条件的断点

假设你以及知道断点是如何工作的了(即使不知道的话,也不用担心,自己百度,你将明白!)。

在某个特定的时间点命中断点是非常重要的,在有些断点中,有些时候需要通过一个痛苦的循环或者递归函数才能让我们的对象等于某个确定的值。此时我们可以使用条件断点!

条件断点是这样的一类断点:只有当满足某个确定的条件时,才会命中断点。可以想象一下:我们只希望当对象在某个确定的状态,或者循环迭代到第nth次时才命中断点。单击Xcode editor中的‘gutter’可以添加一个断点,在断点上单击右键,然后选择‘edit breakpoint’,就可以设置特定的条件了。

conditionalBreakpoints

可以提供一个条件(例如i==12),或者断点忽略次数。另外还可以添加动作,该动作可根据断点自动发生,例如一个debugger command——打印一个值。

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

结论

希望上面的这些关于调试技巧能给你带来帮助。通过上面的这些技巧,可以帮助你减少修改bug的时间,从而把更多的时间用在重要的地方——构建出色的程序!

上面列出来的不是一个完整的调试技巧。另外还有许多技术没有进行讨论,例如在真机中调试问题,远程bug报告,crash报告等。

OC编写使用调试器的更多相关文章

  1. 使用CLRMD编写一个自己的C#调试器

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:使用CLRMD编写一个自己的C#调试器.

  2. Linux C编程学习之开发工具2---GDB调试器

    简介 GDB是一个功能强大的交互式程序调试工具,主要工作在字符界面下. GDB不仅可以用来调试C/C++ 语言编写的程序,还可以用来调试 Pascal.Objective-C,以及Fortran等语言 ...

  3. 使用Python脚本强化LLDB调试器

    LLDB是Xcode自带的调试器,作为一个iOS应用开发程序员,平时我在开发应用时会使用LLDB来调试代码.在逆向应用时,也会用到LLDB来跟踪应用的执行过程. LLDB还内置了一个Python解析器 ...

  4. 使用QtCreator作为ROS调试器

    如果你用过QtCreator,你一定会喜欢上它. 流畅的速度,强大的功能,优雅的外观,友好的界面,一切让人如此舒服.而且它支持从命令行作为调试器启动,只需加上-debug exe即可. 因此我想如果能 ...

  5. iOS 视图调试器(Debug View Hierarchy) 之 初试牛刀

    参考:http://blog.csdn.net/th_gsb/article/details/44856795 由于iOS的界面开发大多都是用代码实现的,编写的时候,那就是看不见摸不着的情况.所以,如 ...

  6. 使用VsCode编写和调试.NET Core项目

    ​ 本来我还想介绍以下VSCode或者donet core,但是发现都是废话,没有必要,大家如果对这个不了解可以直接google这两个关键字,或者也根本不会看我这边文章. ​ 好直接进入主题了,本文的 ...

  7. node.js之调试器

    node.js之调试器 1.在命令行窗口中,可以使用"node debug" 命令来启用调试器,代码如下: node debug<需要被执行的脚本文件名> 接下来根据一 ...

  8. 32位汇编第一讲x86和8086的区别,以及OllyDbg调试器的使用

    32位汇编第一讲x86和8086的区别,以及OllyDbg调试器的使用 一丶32位(x86也称为80386)与8086(16位)汇编的区别 1.寄存器的改变 AX 变为 EAX  可以这样想,16位通 ...

  9. 使用GDB命令行调试器调试C/C++程序

    原文:http://xmodulo.com/gdb-command-line-debugger.html作者: Adrien Brochard 没有调试器的情况下编写程序时最糟糕的状况是什么?编译时跪 ...

随机推荐

  1. DoTween使用

    官网:http://dotween.demigiant.com/ 1.step 这里使用lamda表达式,通过dotween的to方法将其移动到 Vector3(348, 196, 0)的值返回到Ve ...

  2. 【Unity Shaders】学习笔记——SurfaceShader(六)混合纹理

    [Unity Shaders]学习笔记——SurfaceShader(六)混合纹理 转载请注明出处:http://www.cnblogs.com/-867259206/p/5619810.html 写 ...

  3. Oracle数据库(2)

    ; select ename,empno,deptno from emp where job='CLERK'; select * from emp where comm>sal; select ...

  4. PHP isset()与empty()的区别

    PHP的isset()函数 一般用来检测变量是否设置 格式:bool isset ( mixed var [, mixed var [, ...]] ) 功能:检测变量是否设置 返回值: 若变量不存在 ...

  5. IDL与C#混合编程技术

    C# (C Sharp)是微软公司在2000年6月发布的一种新的编程语言.C#与Java有很多的相似之处,包括了诸如单一继承.界面.与Java几乎同样的语法,和编译成中间代码再运行的过程.它又借鉴了D ...

  6. Qt, 我回来了。。。

    说起qt,大学时就有接触,但一直没有深入,这个周六周天利用两于时间重新温习了一下,跟之前用过的vs上的MFC.C++ builder比起来,Qt封装很人性化,库也比较全,写个 一般的小工具很轻松. 参 ...

  7. EnCase v7 search hits in compound files?

    I used to conduct raw search in EnCase v6, and I'd like to see if EnCase v7 raw search could hit key ...

  8. javascript 详解数组

      概念 数组创建 数组读写 数组 VS. 一般对象 相同点 不同点 稀疏数组 数组的length属性 元素增删 数组迭代 二维数组 数组方法 Array.prototype.join Array.p ...

  9. 001MSP430概述

    1.MSP430系列单片机的特点 (1)超低功耗:生来就是为超低功耗设计的,从CPU内核结构到片上外设,以及整个芯片的生产制造都是本着超低功耗的原则来进行的,所以是一款实实在在的超低功耗单片机: (2 ...

  10. 运行ipython后显示WARNING: IPython History requires SQLite, your history will not be saved

    在CentOS6.5下将自带的python2.6升级到python2.7,并安装了ipython,启动ipython后显示如下信息: WARNING: IPython History requires ...