编写高质量代码-OC 第1章 让自己习惯OC


1、视Objective-C为一门动态语言
虽然OC和C++都是在C的基础上加入面向对象特性扩充而成的程序设计语言,OC基于动态运行时类型,而C++基于静态类型。OC编写的程序不能直接编译成可使机器语言(二进制编码),而是在程序运行时,通过运行时(Runtime)把程序转译成可令机器读懂的机器语言。

  • Objective-C是动态语言,C++是静态语言
  • 静态语言执行效率和安全性要比动态语言高,但其简便性没有动态语言高
  • 运行时(Runtime)环境可处理弱类型、函数存在检查工作,会检测注册列表里是否存在对应的函数,类型是否正确,最后确定正确的函数地址,再进行保存寄存器状态、压栈、函数调用等实际操作,确保了objective-C的灵活性。

2、在头文件中尽量减少其他头文件的使用

  • 在头文件(.h)中,关键字“@class”,只是为了在头文件中引用这个类,把这个类作为一个类型来用,这就要求引用的头文件(.h)名与类的名称一样
  • 在头文件(.h)中使用“@class”,在源文件中使用“#import”,不但可以减少不必要的编译时间,降低类之间的耦合度,而且还可以避免循环引用。
  • 在设计类时,尽量多采用协议,避免#import过多,引用不必要的部分。
  • 如果头文件(.h)中有多个类的定义,尽量采用模块方式,只针对性引进所需要的类。

3、尽量使用const、enum来替换预处理#define

  • 尽量避免使用#define预处理命令。#define预处理命令不包含任何的类型信息,仅仅是在编译前做替换操作。它们在重复定义时不会发出警告,容易在整个程序中产生不一致的值。
  • 在源文件(.m)中定义的static const类型常量因为无须全局引用,所以它们的名字不需要包含命名空间。
  • 在头文件(.h)中定义的全局引用的常量,需要关联定义在源文件(.m)中的部分。因为需要被全部引用,所以它们的名字需要包含命名空间,通常是用他们的类名作为命名前缀。
  • 尽量用NS_ENUM和NS_OPTIONS宏来实现枚举。

4、优先使用对象字面量语法而非等效方法

  • 尽量使用对象字面量语法来创建字符串、数字、数组和字典,比常规对象创建方法语法更为简明
  • 完全向下兼容
  • 在数字和字典中,要使用关键字和索引做下标来获取数据
  • 使用对象字面量语法时,容器类的不可使nil,否则运行时将会抛出异常。

5、处理隐藏的返回类型,优先选择实例类型(instancetype)而非id

  • instancetype仅用于返回类型
  • 使用instancetype可避免隐式转换id而造成的欺骗性编译无误通过的现象,防止程序正式运行时出现崩溃现象,提高安全性
  • 在某一个特定区域,可以替代id,并非所有区域都可以替代id

6、尽量使用模块方法与多类建立复合关系

  • #include和#import,其根本就是简单的复制、粘贴,将目标.h文件中内容一字不落的复制到当前文件中,后者可以避免多次的重复引用
  • 以预编译头文件的方式,虽可缩短编译时间,但其维护棘手,不利于广泛应用。
  • 模块功能,其应用不仅仅表现于编译的速度加快,同时在连接框架等方面也非常好用
  • 启动模块功能后,编译器会隐式地把所有的#import都转换成@import

7、明解Objective-C++中的有所为而有所不为

  • C++和Objective-C在定义结构上一样,但是后者的继承是封闭的
  • Objective-C接口中定义的C++类是全局范围,而不是Objective-C类的内嵌类
  • C++和Objective-C的对象模型不能直接兼容,与Objective-C不同的是,C++对象是静态类型的,有运行时系统多态是特殊情况
  • C++和Objective-C有词汇歧义和冲突
  • C++和Objective-C两者功能上有限,Objective C++没有为Objective-C类增加C++的功能,也没有为C++类增加Objective-C的功能