iOS开发Debug和Release的理解

<一>html

参考: http://blog.csdn.net/mad1989/article/details/40658033程序员

1,Debug和Release版本区别?网络

众所周知,咱们进行iOS开发,在Xcode调试程序时,分为两种方式,DebugRelease,在Target的Setting中相信你们应该看到不少选项都分为DebugRelease,方便咱们分别设置,知足调试和发布的不一样需求。app

Release是发行版本,比Debug版本有一些优化,文件比Debug文件小 Debug是调试版本,Debug和Release调用两个不一样的底层库。通俗点讲,咱们开发者本身内部真机或模拟器调试时,使用Debug模式就好,等到想要发布时,也就是说须要大众客户使用时,须要build Release版本,具体区别以下:函数

1、Debug是调试版本,包括的程序信息更多
2、只有Debug版的程序才能设置断点、单步执行、使用TRACE/ASSERT等调试输出语句
3、Release不包含任何调试信息,因此体积小、运行速度快
工具

那么,问题来了,咱们调试程序时,该如何生成(Build)或运行Debug或是Release版本呢?布局

Xcode左上角,点中项目名称-Edit Scheme,或是菜单栏-Product-Scheme-Edit Scheme 弹出界面以下:性能

当你这里设置Debug时,你build/Run后就是debug版本,相应的,修改为Release模式,出来的就是release版本,这里能够很方便切换。学习

2,Archive(归档)的做用?测试

刚开发时,始终不知道这个的做用,只知道要打包生成APP时,须要用这个,那么到底Archive和Release有什么关系呢?

archive是你要上传包的时候,打包。也就是说Archive只跟APP要上传到appStore的时候有关,通常状况下,只有在那个时候才会用Archive,能够这么理解。因此Archive也分为Debug和Release两个,你能够Archive出一个Debug版本的应用也能够Archive出一个Release的应用。

因此说,Archive和Release没有太大的关系,Archive咱们平时通常都不会用到的。

3,Profile

点击运行Profile,profile 以后,会有一个工具选项. 而后你能够查看app 性能

4,Analyze

analyze,是查找静态内存泄漏,之前mrc 的时候会用。Profile和Analyze均可以在Scheme中设置:

总结:

默认run,是debug模式,就是真机联调.
若是你修改成release,是run 的时候, 为发布模式.
直接archive 是系统提供帮助打包的,Archive生成后的文件会小不少~

iOS生成静态库方法-iOS集成静态库-iOS合并静态库_ 参考:

http://blog.sina.com.cn/s/blog_7b9d64af0101jlym.html

<二>

参考: http://www.jianshu.com/p/9c4c92a38468

对于软件开发而言,调试是必须学会的技能,重要性不言而喻。对于调试的技能,基本上是能够迁移的,也就是说你之前在其余平台上掌握的不少调试技巧,不少也是能够用在iOS开发中。不一样语言、不一样IDE、不一样平台的调试,有同性也有个性。今天咱们就来学习一下iOS开发中的调试技巧,语言暂用为OC,IDE固然是强大的Xcode。首先说明下,Xcode已经为咱们调试项目提供了极大的方便。

【1.普通断点】

断点(Breakpoint)绝对是调试程序的第一大选择,也是掌握的基础技能。顾名思义,当程序运行到断点处时会暂停运行。好比断点打在11行,那么程序就会停在11行(注意:程序只运行到了前10行,第11行其实尚未被执行!!!)。只要在代码行旁边点击,就能添加一个断点,再次点击,就能让断点不可用(disable了,仍然存在,只是不起做用了)。在某一行建立断点的快捷键是:command+\

并能在调试过程当中在下方看到参数的值:

【2.条件断点】

以上的断点只是最普通的,咱们还能对断点的属性进行配置,设置条件,使断点更加智能化,右键断点进入编辑对话框:

我以一个循环做为测试代码:

循环中的代码每次都要单步执行,可能这并非我想要的。我想要在i为3的时候中断程序,进行调试,编写条件以下:

设置i==3的条件后,程序就会在该条件时中断,而不会每次到达该位置都中断。中断时输出以下:

同时也能够设置Ignore参数,会忽略前面n次的断点运行,会在第n+1次中断。

调试输出以下:

同时,还能够查看某个函数被调用的次数,设置Action参数以下,注意要选中Automatically continue after evaluating actions.

输出结果以下:

【3.异常断点】

断点的功能不限于上面所述。开发iOS知道,若是咱们由于异常而后程序crash了,代码就直接跑到main.m的main函数中去了。为何就不能跑到出现异常的代码中呢???异常断点就为咱们解决该问题,程序就会在异常出现的那行代码终止。建立异常断点图例以下:

以下所示就建立完成了。若是碰到异常crash时,尝试使用异常断点吧。

【4.符号断点Symbolic Breakpoint】

符号断点的建立也同异常断点。通常符号断点能够在你指定的[类名 方法名]时中断执行。

配置符号断点以下:能够当执行到ViewController类的viewDidLoad方法时中断执行。

若是你的Symbol只写了一个函数名,那么就会在出现该函数名的地方就中断执行。以下,就会在运行到doAnimation的时候中断。是否是很强大呢?

【5.Analyze分析器】

Analyze分析器是一种静态的工具,能够对咱们的程序进行分析,找出咱们未使用的变量,或一些死存储。执行Analyze以下:Product-->Analyze. 以下蓝色的标记就是静态分析的结果。

固然,咱们能够设置在编译程序的时候同时Analyze,把下列选项设为Yes便可。

【6.Profile检查器】

这个工具实在是太NB了,三言两语说不完,贴张图,你们感觉一下。一样在Product-->Profile中打开。

【7.僵尸对象】

iOS中把那些已经release但还没彻底消失的对象叫作僵尸对象,对已经release的对象再次释放,就会发生异常。虽然自从使用ARC后,因为对象释放产生的异常已经大大变少,但偶尔还会出现。开启僵尸对象模式后,就能快速定位到异常位置。开启方式以下:Product-->Scheme-->Edit Scheme. 勾选Enable Zombie Objects便可。

【8.lldb命令】

Xcode中使用llvm编译器,公认为最好的C、C++、OC、Swift编译器。而lldb是llvm中的调试器,咱们可使用一些简单的命令进行调试,我仍是把上面的循环代码做为测试代码。

断点调试中,使用po命令、print命令在Console控制台打印出变量信息:

【9.NSLog打印】

应该说NSLog打印信息是初学者最喜欢的调试手法,也是最简单的调试,经过打印出的信息查看程序运行的路径。可是打印出的信息较少,自己NSLog效率较低,有人使用宏作了部分优化,代码以下:可以打印出所在类名、所在方法名、详细时间、行号。

#import "ViewController.h"

#define NSLog(format, ...) do { \

fprintf(stderr, " %s\n", \

[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], \

__LINE__, __func__); \

(NSLog)((format), ##__VA_ARGS__); \

fprintf(stderr, "-------\n"); \

} while (0)

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

for (int i = 0; i < 5; i++) {

NSLog(@"个人值:%d",i);

}

}

@end

打印结果以下:

 

【10.生命周期方法init,dealloc】

对于ViewController来讲,有两个生命周期函数咱们能够进行重写,也就是init和dealloc方法。对于某些对象的状态,咱们能够在这两个方法中查看。尤为是在dealloc中能够看到当ViewController退出的时候某个对象是否release。

- (instancetype)init

{

self = [super init];

if (self) {

//初始化语句;

}

return self;

}

- (void)dealloc

{

//释放后调用;

}

【11.查看代码运行时间】

有时候咱们想要准确的知道某段代码、某个循环执行的时间,而后分析效率等问题,这个时候就须要执行时间是多少。正好看到网上已经有人作了这个工做,我就直接摘下来了。正好也用了宏的方式计算时间,咱们只要在须要计算时间的代码块先后写上TICK,TOCK宏便可。固然,原理也是很是的简单,也就是使用NSDate计算差值。

#import "ViewController.h"

#define TICK  NSDate *startTime = [NSDate date]

#define TOCK  NSLog(@"Time: %f", -[startTime timeIntervalSinceNow])

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

TICK;

for (int i = 0; i < 5; i++) {

NSLog(@"个人值:%d",i);

}

TOCK;

}

@end

打印结果以下:

【12.手机截屏】

手机截屏也算调试?哈哈。其实也算是开发中的一个小技巧哈。其实你们都会在iPhone上同时按电源键+Home键截屏,而后使用各类通信软件发给其余人,这个略显不方便。咱们来使用Xcode中的方式截屏。当手机接上电脑后,注意要把调试设备选为本身的手机:

而后选择Debug-->View Debugging-->Take Screenshot...  .而后能够看到手机屏幕已经在你的电脑桌面了。是否是比直接在手机上操做方便多了呢?这样就能够快速的发给其余开发者、PM等人了。

【13.viewDidLoad不建议写太多代码】

我的建议不要在viewDidLoad方法中写入太多代码。尤为是涉及该界面中的动画的时候,由于执行viewDidLoad方法的时候,界面可能还没彻底加载出来,若是此时把动画放在viewDidLoad中,可能会形成动画没法显示。固然也不建议把耗时的网络请求和动画效果都放在viewDidLoad中,界面的阻塞也会形成动画没法显示。能够尝试把动画放在viewDidAppear,viewWillAppear方法中。对于这类涉及UI的问题,调试也是比较麻烦的。。。

【14.视图调试】

现在iOS开发的UI设计有不少种方式,好比storyboard,xib,代码实现。对于stoayboard,xib可视化实现是比较简单的,可是对于一些“iOS老程序员”而言,都喜欢使用代码实现UI,而且可能UI层次还比较复杂。这样就给咱们新接手项目的开发者带来不少困扰。如何快速查看一个复杂UI的界面层次和布局,最快的方法就是用到视图调试。

当项目运行到某一个界面(能够是模拟器或真机)时,开启视图调试,点击按钮如图:

这样就会进入试图调试,你能够很方便的查看这个界面。这里能够看到控件之间的层次关系。

左侧的树形层次图能够在查看线程、队列和UI之间切换:

【15】经常使用的编译宏定义:可让代码在不一样的编译状况下执行。

(1)__OPTIMIZE__  :用于release和debug的判断,当选择了__OPTIMIZE__  时,可让代码在release时执行,在debug时不执行。示例以下:

#ifndef __OPTIMIZE__

//这里执行的是debug模式下

else

//这里执行的是release模式下

#endif

(2)__i386__ 与 __x86_64__  :用于模拟器环境和真机环境的判断。知足该条件的代码只在模拟器下执行。示例代码以下:

#if defined (__i386__) || defined (__x86_64__)

//模拟器下执行

#else

//真机下执行

#endif

(3)__IPHONE_OS_VERSION_MAX_ALLOWED  :当前编译的SDK版本,能够与__IPHONE_9_0等宏定义进行比较,进行不一样版本下代码的执行。示例以下:

if (__IPHONE_OS_VERSION_MAX_ALLOWED == __IPHONE_9_0) {

//若是当前SDK版本为9.0是执行这里的代码

}else{

//不然执行这里

}

【16】预编译宏 #ifdef    #else  #endif

#ifdef ****

//代码1

else

//代码2

#endif

意思是 若是标识符****已被#define命令定义过,则对代码1进行编译,不然对代码2进行编译。

同时也有#ifndef,则与#ifdef恰好相反。

做者:(乞力马...)  原文 http://mp.weixin.qq.com/s?__biz=MjM5OTM0MzIwMQ==&mid=404478233&idx=2&sn=ae55d4f70fce47c11958f0b8536f4370&scene=23&srcid=0322WVWcizsblwnzfHYWq13O#rd

相关文章
相关标签/搜索