Effective Objective-C的读书心得
了解Objective-C语言的起源
Objective-C从Smalltalk语言是从Smalltalk语言演化而来,
Smalltalk是消息语言的鼻祖。Objective-C是C语言的超集,在C语言基础上添加了面向对象等特性,可能一开始接触时你会觉得语法有点奇怪,那是因为Objective-C使用了动态绑定的消息结构,而Java,C++等等语言使用的是函数调用。
消息结构与函数调用的关键区别在于:函数调用的语言,在编译阶段由编译器生成一些虚方法表,在运行时从这个表找到所要执行的方法去执行。而使用了动态绑定的消息结构在运行时接到一条消息,接下来要执行什么代码是运行期决定的,而不是编译器。
在类的文件中尽量少引用其他头文件
- 如果需要引用一个类文件时,只是需要使用类名,不需要知道其中细节,可以用@class xx.h,这样做的好处会减少一定的编译时间。如果是用的#import全部导入的话,会出现a.h import了b.h,当c.h 又import a.h时,把b.h也都导入了,如果只是用到类名,真的比较浪费,也不够优雅
- 有时候无法使用@class向前声明,比如某个类要遵循一项协议,这个协议在另外一个类中声明的,可以将协议这部分单独放在一个头文件,或者放在分类当中,以降低引用成本。
多用字面量语法,少用与之等价的方法
- 传统创建数组方法:
*languages 1
2
3NSString *Swift = [languages objectAtIndex:2];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"key", @"value", nil];
NSString *value = [languages objectForKey:@"key"]; - 字面量:
*languages 1
2
3NSString *Swift = languages[2];
NSDictionary *dict = @{@"key" : @"value"};
NSString *value = languages[@"key"];这样做的好处:使代码更简洁,易读,也会避免nil问题。比如languages数据中 someObject 如果为nil时,字面量语法就会抛出异常,而使用传统方法创建的languages数组值确是@[@”PHP”, @”Objective-C”];因为字面量语法其实是一种语法糖,效果是先创建了一个数组,然后再把括号中的对象都加到数组中来。
不过字面量语法有一个小缺点就是创建的数组,字符串等等对象都是不可变的,如果想要可变的对象需要自己多执行一步mutableCopy,例如
1 | ``` |
输出 110
==操作符只是比较了两个指针,而不是指针所指的对象
以“类族模式”隐藏实现细节
为什么下面这段if 永远为false
1 | if ([maybeAnArray class] == [NSArray class]) { |
因为[maybeAnArray class] 的返回永远不会是NSArray,NSArray是一个类族,返回的值一直都是NSArray的实体子类。大部分collection类都是某个类族中的’抽象基类’
所以上面的if想要有机会执行的话要改成
1 | id maybeAnArray = @[]; |
这样判断的意思是,maybeAnArray这个对象是否是NSArray类族中的一员
** 使用类族的好处:可以把实现细节隐藏再一套简单的公共接口后面 **
既有类中使用关联对象存放自定义数据
这条讲的是objc_setAssociatedObject和objc_getAssociatedObject,如何使用在这里就不多说了。值得强调的一点是,用关联对象可能会引入难于查找的bug,毕竟是在runtime阶段,所以可能要看情况谨慎选择