正在加载今日诗词....
4 min read

iOS 高效编码(一)

objective-c 高效编码的读书笔记 第一篇
iOS 高效编码(一)

在类的头文件中尽量少运入其他头文件

1、 除非有必要,否则不要引入头文件. 一般来说,应该在类的头文件中使用向前引用来声明一个类,并在实现文件中,引入那些类的头文件.
好处: 减少编译时间,解决互相引用问题,降低类之间的耦合.
2、 如果无法使用向前引用,比如声明某个类遵守一项协议.这种情况下,尽量把声明移到"class-continuation分类"中.
如果不行就把协议单独放在一个头文件中,然后将其引入.
两者的区别在于: 协议与遵循协议类的关系,是否有强烈的依赖关系.比如委托协议(delegate protocol).

多用字面量语法,少用与之等价的方法

  1. 应该使用字面量语法来创建字符串、数值、数组、字典。
  2. 应该使用下标操作访问数组或者字典

优点 : 简洁高效,更安全(对nil的处理),无关语法易读性强
缺点 : 除了字符串外,所创建的对象必须属于Foundation框架,创建出的对象都是不可变的,如果想生成可变对象,需要mutableCopy一份

多使用类型常量,少用#define 预处理指令

  1. 不要用预处理指令定义常量. 这样定义出来的常量不含类型信息,编译器只是会在编译前据此执行查找和替换操作.即使有人重新定义了常量值,编译器也不会产生警告信息,这将导致程序中常量值不一致.
  2. 如果常量只在某个类中使用,不提供给外部.则建议在类的实现文件中使用static const来定义 "只在编译单元内可见的常量(translation-unit-specific constant)". 命名规范,因为不出现在全局符号表中,所以无须为其名称加前缀. 举例动画时长: static const NSTimeInterval kAnimationDuration = 0.3(此种写法,常量只会出现在编译单元也就是某类的实现文件中,实际上,编译器根本不会创建符号,而是像#define预处理指令一样,把所有遇到的常量都替换成常值)
  3. 对于全局符号表类型的常量,一般在头文件中使用extern来声明全局常量,并在相应的实现文件中定义其值. 命名规范:一般其名称前面会用与之相关的类名做前缀. 主要是因为OC没有命名空间namespace,全局变量会出现变量名冲突duplicate symbol的编译错误.
// header file
extern NSString *const DDLoginManagerDidLoginNotification;

// implementation file
NSString *const DDLoginManagerDidLoginNotification = @"DDLoginManagerDidLoginNotification";

这里const 修饰的 DDLoginManagerDidLoginNotification是一个字符串指针变量,不能够被修改.

用枚举Enum表示状态、选项、状态码 ,禁止使用魔法数字

1、 应该使用枚举类标识状态机的状态,传递给方法的选项以及状态码等值,给这些值起易懂的名字.
2、 如果把传递给某个方法的选项为枚举类型,而多个选项又可以同时使用,则可以将枚举选项设置为2的幂数,以便通过按位与或操作将其结合起来

enum UIViewAutoresizing {
    UIViewAutoresizingNone                  = 0,
    UIViewAutoresizingFlexibleLeftMargin    = 1 << 0,
    UIViewAutoresizingFlexibleWidth         = 2 << 0,
    UIViewAutoresizingFlexibleRightMargin   = 3 << 0,
    UIViewAutoresizingFlexibleTopMargin     = 4 << 0,
    UIViewAutoresizingFlexibleHeight        = 5 << 0,
    UIViewAutoresizingFlexibleBottomMargin  = 6 << 0,
}

3、用NS_ENUMNS_OPTION宏来定义枚举类型,并指明其底层数据类型. 这样做可以确保枚举是用开发者所选的底层数据类型来实现出来的,而不会采用编译器所选的类型.

/*!
 @typedef ChauffeureCarServiceState
 @brief 某地区开通专车服务的状态
 @constant ChauffeureCarServiceStateNone 未开通.
 @constant ChauffeureCarServiceStateEstablished 已开通
 */
typedef enum : NSUInteger {
    /** 专车服务 未开通*/
    ChauffeureCarServiceStateNone = 1,
    /** 专车服务 已开通*/
    ChauffeureCarServiceStateEstablished = 2,
} ChauffeureCarServiceState;

------------------------- snippet sample
/*!
 @typedef <#Enum Name#>
 @brief 状态
 @constant <#Enum State 0#> <#state 0 description#>.
 @constant <#Enum State 1#> <#state 1 description#>
 */
typedef enum : <#DataType#> {
    <#/** state 0 description */#>
    <#Enum State 0#> = <#Value 0#>,
    <#/** state 1 description */#>
    <#Enum State 1#> = <#Value 1#>,
} <#Enum Name#>;

4、在处理枚举类型的switch语句中不要实现默认default分支. 这样的话,加入新枚举之后,编译器就会提示开发者,switch语句并未处理所有的枚举.