第五章 内存管理
1.ARC并不会调用retain
、release
等方法,而是直接调用其底层C语言版本objc_retain
等,所以ARC没有普通的OC消息派发机制。
2.如果setter
方法像下面这样写,当新值和旧值相同时就程序就会崩溃。
-(void)setObject:(id)object{
[_object release];
_object=[object retain];
}
3.ARC中的命名规则:如果方法名以alloc
、new
、copy
、mutableCopy
开头,则返回对象归调用者所有,否则返回的对象会自动释放。
4.dealloc方法里要释放指向其他对象的引用,取消键值观测(KVO)和NSNotificationCenter
通知,不要在这里执行异步任务或应该在正常状态下执行的任务,因为这是的对象已经处于正在回收状态了。
5.ARC默认不生成安全处理异常的代码,设置-fobjc-arc-exceptions标志后可以开启,不过会导致应用程序变大,效率变低。
6.unsafe_unretain
和weak
都可以用来消除循环引用,区别是前者在引用移除后仍然指向已经回收的对象,后者则会自动设为nil
,所以使用weak
会安全一点,因为向nil
发送消息不会报错。
7.利用自动释放池可以避免内存峰值的出现。
第六章 块与大中枢派发
1.下图是块的内部结构:
上图中首个变量是个isa指针,所以块本身是一个对象。那么块和普通函数有什么区别呢?除了块是个对象外,其实最大的区别就是块比函数多了个上下文环境,块内部可以调用外部的变量,对应上图的variables
,而descriptor
内部则会对捕获的变量进行管理。
2.块分为全局块NSConcreteGlobalBlock
、栈块NSConcreteStackBlock
、堆块NSConcreteMallocBlock
,在ARC中只有全局块和堆块了。
3.利用typedef
创建块,然后将handler块作为参数传给方法,以降低代码分散程度。这种方法编写类的时候特别要注意块的保留环,记得要把块在适当时机释放掉,解除保留环。在AFNetworking中,是把所有competition块保存在字典中,当请求结束时,再移除,其他开源库的做法也都大同小异。
4.GCD和NSOperationQueue
:前者是纯C的API,且更加轻量,后者是Objective-C对象,可以取消操作、设置依赖关系、同一队列中各操作的优先级设置。
5.不要使用dispatch_get_current_queue
,因为往往A线程里面又有B线程,所以在B中检测当前线程就会产生歧义。
第七章 系统框架
1.多用块枚举,少用for循环,另外也可以使用for in这种快速遍历的方法。
2.load
和initialize
里面的代码一定要精简。不要在里面调用其他类的方法,因为多个类之间执行load
的顺序是不确定的,而且load
不参与继承机制。initialize
会在类被第一次调用时执行一次,和load
一样,不要再里面调用其他类的方法。
3.NSTimer
会保留目标对象,所以很容易造成循环引用,调用invalidate
方法可以使timer失效,但是别把这项工作交给调用者,你永远无法保证调用者一定会调用invalidate
。
结语
这本书其实早就看完了,写这几篇博客时,这本书差不多看了快三遍了,里面很多知识点对提升编程质量还是很有帮助的,在看一些开源iOS框架的时候,很多细节上的处理都能在这本书上找到解释。