Effective Objective-C - 系统框架
前言
NSObject 属于 Foundation 框架,我们写的OC代码全部都是基于这些基本系统框架之上的
笔记
熟悉系统框架
- 将一系列代码封装为动态库,并在其中放入描述其接口的头文件,这样做出来的东西就叫框架。所有iOS平台的系统框架都是动态库
- NS开头的基本都是Foundation框架,与Foundation框架对应的一个CoreFoundation框架,他是C语言的API
- 使用toll-free bridging可以实现Foundation的OC对象和CoreFoundation的C数据结构互相转换
- 使用C语言的API可以绕过OC的runtime机制,加快运行速度;但是使用C语言的API时,需要注意内存管理的问题
多用块枚举,少用for循环
使用OC1.0的 NSEnumerator 来遍历
1
2
3
4
5
6
7
8
9
10
11
12
13
14NSArray *array = /*...*/;
NSEnumerator *enumerator = [array objectEnumerator];
id object;
while ((object = [enumerator nextObject]) != nil) {
// do something
}
NSDictionary *dict = /*...*/;
NSEnumerator *enum = [dict keyEnumerator];
id key;
while ((key = [enum nextObject]) != nil) {
id value = dict[key];
// do something
}框架还提供反向遍历的enum接口
使用OC2.0的 快速遍历 ,也就是for in
基于块的遍历方式,对于NSArray有
-(void)enumerateObjectsUsingBlock:(void(^)(id object, NSUinteger idx, BOOL *stop))block;
;其他的collection也有相对应的方法。使用block方法,可以获取更多的信息
对自定义其内存管理语义的collection使用无缝桥接
使用无缝桥接来转换Foundation和CoreFoundation
1
2NSArray *array = @[@1, @2, @3];
CFArrayRef aCFArray = (__bridge CFArrayRef)array;__bridge 还有疑问
NSDictionary 对于key是copy,对于value则是retain。要想改变期内存语义的话呢,只能使用CoreFoundation了,具体的看书~
构建缓存时选用NSCache而非NSDictionary
- NSCache在系统低内存时会自动删减缓存,而且优先删减的是最长时间没有使用过的缓存
- NSCache的key是retain的,不是copy的。因为很多时候,这个key的对象不支持copy
- 线程安全,这点对于缓存来说很关键
精简initialize与load的实现代码
+ (void)load;
每个类必定会调用该方法,而且仅调用一次。当包含类的程序库载入系统时,就会执行此方法,也就是程序启动的时候- 如果分类和类都定义了load方法,那么先调用类的,再调用分类的
- 在执行类的的load之前,会先执行多有超类的load方法
- load方法和其他不一样,如果子类没有实现的话,不管超类有没有,他都不会继承该方法
- load方法要精简,程序在执行没有load方法的时候都会阻塞
- 尽量不要使用load方法
+ (void)initialize;
在程序第一次使用这个类的时候,会调用该方法。它也只会运行一次。不应该由代码来显式调用。- initialize只有在程序用到该类的时候才会调用,属于惰性调用;它由运行期系统来调用。调用它的时候,系统中的个各类都是可以正常使用的,这一点和load方法不同
别忘了NSTimer会保留其目标对象
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.