一、了解Objective-C语言起源
1、 Objective-C使用的是“消息结构”而非“函数调用”。 Objective-C语言有Smalltalk演化而来。
二者之间的区别
- 使用消息语言结构的语言,其运行时所对应的代码由运行环境决定;而使用函数调用的语言,由编译器决定。
- 如果调用的函数是多态的,函数调用按照“虚方法表”来查出到底应该执行哪个函数实现;而采用消息结构的语言,无论是多态,总是在运行时才会去查找所要执行的方法。实际上编译器甚至不关心接受消息的对象是何种类型。接受消息的对象也要在运行时处理,这个过程叫动态绑定。
- Objective-C的重要工作都由“运行期组件”(runtime component)而非编译器俩完成。
总结
- Objective-C为C语言添加了面向对象的特性,是它的超集,Objective-C使用动态绑定的消息结构,也就说,在运行才会检查对象的类型。接收一条消息过后,究竟应该执行何种代码,有运行期环境而非编译器来决定
二、在类的头文件中尽量少引入其他头文件
- 除非确有必要,否则不要引入头文件。应在某各类的头文件中使用向前声明(@class xxx;)来提及别的类,并在实现文件中引入那些类的头文件。这样做可以尽量降低类之间的藕合。还可以避免相互引用的问题,并且编译时不会编译引用的全部细节,只需要知道类名就可以,并告诉编译器。
- 有事无法使用向前声明,比如要声明某各类遵循一项协议。这种情况下,尽量把“该类遵循某协议”的这条声明一直“class-continuation”分类中。如果不行的话,就把协议单独放在一个头文件中,然后将其引入。
三、多用字面量语法,少用与之等价的方法
- 应该使用字面量语法来创建字符串、数组、字典。与创建此类对象的常规方法相比,更加简明扼要。
- 应该通过取下标来访问数组下标或者字典中的键所对应的元素
- 用字面量语法创建的数组或者字典,若值中有nil,则会抛出异常。因此,务必要确保值里不含nil。而等价方法,在创建的时候,不小心用了控制对象,那么方法就会在首个nil方法进行提前结束。
四、多用类型常亮,少用#define预处理指令
- 不要硬预处理制定定义常量。这样定义出来的常量不含类型信息,编译器只是会在编译钱据此执行查找与替换操作。即使有人重新定义了常量值,编译器也不会产生警告信息,这样会导致应用程序中的常量不一致
- 在实现文件中使用static const 来定义“只在编译单元内可见的常量”,由于此类常量不在全局符号中,所以无需为其名称加前缀,如:
static const NSTimeInterval kAnimationDuration = 0.3;复制代码
- 在头文件中使用extern来声明全局常量,并在相关实现文件中定义其值。这种常量要出现在全局符号中,所以其名称应加以去个,通常用与之相关的类名做前缀。如: 在头文件中
extern NSString *const EOCStringConstant;复制代码
在实现文件中
NSString *const EOCStringConstant = @"VALUE";复制代码
五、用枚举表示状态、选项、状态码
- 应该用枚举表示状态机的状态、传递给方法的选项以及状态码等值,给这些值起个易懂的名字。
enum EOCConnectionState { EOCConnectionStateDisconnected, EOCConnectionStateDisconnecting, EOCConnectionStateconnected};typedef enum EOCConnectionState EOCConnectionState;复制代码
- 果果把传递给魔偶个方法的选项表示为枚举类型,而多个选项有可同时使用,那么就将各选项定义为2的幂,一边通过按位或者操作将其结合起来。
enum UIViewAutoresizing { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, UIViewAutoresizingFlexibleRightMargin = 1 << 2, UIViewAutoresizingFlexibleTopMargin = 1 << 3, UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5};复制代码
- 用NS_ENUM 与 NS_OPTIONS 宏来定义枚举类型,并指明其底层数据类型。这样做可以确保枚举是用开发者所选的底层数据类型实现出来的,而不会采用编译器所选的类型。
typedef NS_ENUM(NSUInteger, EOCConnectionState) { EOCConnectionStateDisconnected = 1, EOCConnectionStateDisconnecting, EOCConnectionStateconnected};typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, UIViewAutoresizingFlexibleRightMargin = 1 << 2, UIViewAutoresizingFlexibleTopMargin = 1 << 3, UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5}复制代码
- 在处理枚举类型的switch语句中不要实现的default分支。这样的话,加入新枚举之后,编译器就会提示开发者:switch语句并没有处理所以枚举。(但是我运行发现编辑器并没有警告,加了default之后)
switch (_currentState) { case EOCConnectionStateDisconnected: break; case EOCConnectionStateDisconnecting: break; case EOCConnectionStateconnected: break; }复制代码