iOS Code Review纪要 2017-10-26

iOS Code Review纪要

Hi,All

今天 code review 提到的点记录如下:

1. 固定字符串使用宏定义好还是字符串好?

  1. 讨论使用宏的缺陷:

    不能区分类型

  2. 宏定义复杂的话,操作宏可能会出现问题.

  3. 使用宏定义时留意定义重复引起异常

    系统解决宏重复定义的方式是提前使用编译控制指令判断,比如:

1
2
3
4
5
#ifndef NS_ASSUME_NONNULL_BEGIN
#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
#endif
  1. 宏的优点,可移植性高,简洁明了,一看就懂。

2.相同功能再不同版本系统 API 不一致,可以在应用内部进行封装。

比如 UIAlertView(2.0-9.0) | UIAlertController(8.0+) 可以封装为一个 SMAlert 在里面进行兼容逻辑处理。

3. 文件行数偏多,可以根据功能拆分为不同的文件。

让每个类各司其职

4. 简单的 if else 语句考虑是否可以简化为三段式语法。比如:

1
2
3
4
5
if (granted){
tempDataStore.userSetting.hasAccessToAB = YES;
} else {
tempDataStore.userSetting.hasAccessToAB = NO;
}

转化为

tempDataStore.userSetting.hasAccessToAB = granted;

5. @autoreleasepool

1) @autoreleasepool autoreleasepool可以理解成一个双向链表的结构的堆栈,包含要释放的对象,每个节点是autoreleasepoolpage 对象,每个 page 最大的空间是虚拟内存的一页大小(4096),

2) OC 使用 @autoreleasepool 更加有效的办法是将其放置在循环内部,这样能及时将对象释放掉.

3) 在 iOS 6以及之前,新建的线程需要实现@autoreleasepool runloop 结束前释放对象可以参考 NSObject.mm

4) 每个线程都要有对应的autoreleasepool。系统已经帮我们写好了主线程的autoreleaepool(main.m中)。

关于autoreleasepool的介绍

6. 代码风格统一,比如函数名后面大括号的位置,保持书写一致。

7. 分支 if else 尽量配对使用,保证逻辑完整,if 里面尽量包含主要的处理逻辑。是否需要在 if 里面就执行 return 值得考虑。

8. 关于异常捕获,try catch, 考虑是否需要添加 try catch . 添加 try catch 理由是防止程序崩溃,提供良好用户体验。不添加 try catch 理由是让程序及早崩溃,防止错误蔓延,同时增加 try catch 也会消耗系统的性能。开发过程考虑使用断言及早暴露程序的问题。考虑根据实际可能出现的异常情况做不同的异常处理。

OC对它支持并不好,同时try catch会造成内存泄露,因为捕获异常的时候会破坏ARC机制,导致对象释放不了,如果非要加try的话,尽量不要在try中创建对象。

try-catch链接1

try-catch链接2

9. 关于私有方法名的使用,私有方法是需要在程序里单独建一个 check 文件去记录使用私有方法的地方和版本(备案)。为了以后的维护方便。

10. NSDateFormatter 这种比较消耗性能的类,如果分配内存次数过多的话,可以考虑做一个成员或者静态变量,没必要每次都分配。

11. 一个方法内部构建好的可变资源(比如可变数组)返回给调用者的时候,为了防止调用者任意篡改,可以考虑在返回的时候进行 copy 将可变的资源变为不可变资源(可变数组转化为不可变数组)。

12. 使用底层存储机制的时候考虑到之后的维护性,需要选用合适的存储机制,比如 OC 上的 CoreData 还有 Sqlite ,技术选型的时候要根据自身的需求结合具体技术的特点去选择。

显示评论