OC编写使用调试器

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

  1. 记录信息

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

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

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

      2.使用控制台日志

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

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

      3.使用NSLog

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

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

将断点移动到循环中(不管放在循环体什么位置),确保在断点处会项之前那样记录一条消息,但这里需要选上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. c# 清空txt文本文件的值

    FileStream fs1 = null; try { fs1 = new FileStream(@"C:\db.txt", FileMode.Truncate, FileAcc ...

  2. php中若干模块的安装

    1.php的mysql扩展pdo_mysql(在php源码所在目录) 1.1 进入 PHP 的软件包 pdo 扩展目录中   cd /usr/local/services/php-5.6.5/ext/ ...

  3. C++ Namespace 详解

    命名空间的定义格式为:(取自C++标准文档) named-namespace-definition: namespace identifier { namespace-body } unnamed-n ...

  4. 【.NET】对文件的对称加密

    using System;using System.IO;using System.Security.Cryptography;namespace ConsoleApp_SymmetricalEncr ...

  5. C++记录debug信息的log类

    取自:http://www.viksoe.dk/code/all_mfc.htm,里面有各种MFC常用的类 // LogFile.h: interface for the CLogFile class ...

  6. Android Malware Analysis

    A friend of mine asked me help him to examine his Android 5.0 smartphone. He did not say what's wron ...

  7. 基于s5pv210嵌入式系统busybox文件系统移植

    基于s5pv210嵌入式系统busybox文件系统移植 1.下载源码 busybox.net/downloads下载最新版的busybox源码,最新源码为1.21.1 2.解压源码文件 tar xvf ...

  8. NC V6 安装目录各文件夹作用描述

    ant:存放Apache Ant,用来执行EJB的构建. bin: 存放nc部署和系统监控等命令.configsys.log部署日志(包含NC中间件.WAS中间件等部署信息)以及NC_Client文件 ...

  9. 如何获取tableview中当前选中的cell

    当我们点击某个cell时,会执行下面这个方法,方法中调用另一方法执行具体操作: - (void)tableView:(UITableView *)tableView didSelectRowAtInd ...

  10. Linux下tftp安装与配置

    1. 背景 开发板在u-boot下从pc获取文件的方式有三种: 1)dnw传输:http://www.cnblogs.com/tanghuimin0713/p/3614768.html 2)串口传输: ...