涉及到质量问题,这就是一个很大的话题,包括不少方面,好比代码书写的质量,开发流程的规范,项目管理的到位,测试的最后把关等各个环节。编码须要规范,命名须要有意义;接口低耦合、高内聚、易扩展,代码能重用、避免重复代码;提交代码后须要作CodeReview;Release前,自测须要充分,包括单元测试、和其余模块(服务器)的联调测试,网络性能测试,不一样机型、不一样系统版本、越狱与否等各个方面的测试;经过冒烟测试后才交于QA测试等等。在这里,咱们主要分享从开发人员的角度如何提升产品质量,包含的内容以下:数组
从上面能够看到,iOS开发中常见的异常包括如下几种:
NSInvalidArgumentException
NSRangeException
NSGenericException
NSInternalInconsistencyException
NSFileHandleOperationException缓存
非法参数异常(NSInvalidArgumentException)是 Objective - C 代码最常出现的错误,因此平时在写代码的时候,须要多加注意,增强对参数的检查,避免传入非法参数致使异常,其中尤以nil参数为甚。服务器
(1) NSDictionary不能删除nil的key
(2) NSDictionary不能添加nil的对象
(3) 不能插入nil的对象
(4) 其余一些nil参数
网络
越界异常(NSRangeException)也是比较常出现的异常,有以下几种类型:函数
好比数组长度count, index的下标范围[0, count -1], 在开发时,可能index的最大值超过数组的范围;
工具
这样会有很大的不肯定性, 多是一个很大的整数值性能
这里的值达到32位和64位整数的最大值,确定是一个不正常的参数,好比:单元测试
若是找不到str ,则返回NSNotFound,32位下它就是2147483647,64位下18446744073709551615 ,将它做为参数传递则会致使NSRangeException。测试
若是一个数组刚刚初始化,仍是空的,就对它进行相关操做ui
因此,为了不NSRangeException的发生,必须对传入的index参数进行合法性检查,是否在集合数据的个数范围内。
NSGenericException这个异常最容易出如今foreach操做中,在for in循环中若是修改所遍历的数组,不管你是add或remove,都会出错,好比:
执行上面的代码会出现如下的错误:
缘由就在这 "for in",它的内部遍历使用了相似 Iterator进行迭代遍历,一旦元素变更,以前的元素所有被失效,因此在foreach的循环当中,最好不要去进行元素的修改动做,若须要修改,循环改成for遍历,因为内部机制不一样,不会产生修改后结果失效的问题。
这也是内存不足的问题,没法分配足够的内存空间
处理文件时的一些异常,最多见的仍是存储空间不足的问题,好比应用频繁的保存文档,缓存资料或者处理比较大的数据:
因此在文件处理里,须要考虑到手机存储空间的问题。
在进行函数调用的时候,若是有NSError的参数传递,最好都处理如下,特别是一些网络和文件的处理,好比:
文件操做错误
好比在删除文件时,有可能发生错误,咱们须要作一些处理
网络处理错误
在使用NSURLConnection进行网络请求时,发生错误是不免的,必须作相应处理
在APP的运行过程当中,不免会有I/O的操做,通常的状况,从技术的角度来看也不会出什么问题,可是业务逻辑上可能就须要特别注意了,好比APP升级版本后,可能保存缓存数据的格式发生变化了,读取数据后的处理逻辑也就相应发生变化,这时就须要考虑兼容旧版本数据的处理,不然对升级用户了说,极可能因为异常发生崩溃。
客户端开发时,对接收到的服务器数据,须要特别当心,由于通过网络传输回来的数据都是不可信的,什么问题均可能发生,好比协议中该有的字段没有,是整数型的字段结果传了一个子串,Json格式的内容变成xml了…,因此咱们在解析服务器数据时,须要有充分的异常处理机制。
在开发完成后,须要对代码进行静态检查,这样能发现一些内存泄露以及一些warning。
在MRC的时候,内存泄露是个大问题,一不当心就会中招
注意上面的代码并非L63行存在泄漏,咱们点击“Potential leak of an object”前面的箭头,指示会出现一些变化,以下图。
alloc一个对象的时候,其内存计数内存计数(retain count)+1
由于content的setter方发会将object的内存计数+1,以下代码,content是retain属性。执行完L62代码后,self.content的内存计数就为 2
建议修改方案:
在ARC下,这方面的问题就少不少了,但也仍是会出现的,好比:
使用CF CG有关的函数,内存的释放仍是须要手动调用的,不调用则会形成内存泄漏
CFUUIDRef和CFStringRef都须要手动释放
CGImageRef相似也须要手动释放
在iOS中,怎么避免内存泄漏的产生呢?除了开发经验的积累,咱们也能够经过两个方法来发现内存泄漏,以便及时修复,一个就是上面讲到的静态分析(Analyze),比较简单;对于静态没有检测出来的内存泄露问题,须要使用动态的方法,下一节来分享。
Unused、Never read....这个比较简单,修改便可。
Tag不等于一、2和3的时候,就会出现很问题了。len is a garbage value。建议在声明变量时,同时进行初始化。
对完美主义者来讲,warning在Xcode里始终都比较碍眼,直接消除。
Analyze分析内存泄露不能把全部的内存泄露查出来,有的内存泄露是在运行时,用户操做时才产生的。在 C、C++混编时,对于C++的内存分配,也是须要手动释放,好比iOS中使用Openssl来进行RSA的加解密操做,其中就有不少的内存操做,若是不进行手动释放,Analyze是检查不出来的,这个时候就须要用到Instruments了。
初始化
释放的代码注释掉
这个时候使用Analyze分析,一点内存泄漏也没有,咱们使用Instruments来分析
“Product” -> “Profile”:
按上面操做,build成功后跳出Instruments工具,选择Leaks工具,这时候Instruments工具就运行起来了,显示效果以下:
点击上面的”红色的圆圈”,才会启动对应的APP,这时”红色的圆圈”变成”黑色的正方形”:
这时用户就能够在APP上任意操做,查看内存使用状况,选择”Leak Checks”项,右边的图中,若是是”绿色的勾”表示内存使用正常,”红色的叉”则表示有内存泄漏,这时点击”黑色的正方形”,让APP暂停下来。
这时你只要在”Reponsible Frame”中双击对应的方法,就会跳转到具体的代码,好比双击”MS_RSA_Public_E”:
表明malloc后没有使用free释放OutBuf的内存。
修改以下: