野火🔥

生命如野火,骄傲而顽强

《Effective Objective-C 2.0》读书笔记3---tips

读书笔记第三篇,主要就是学习总结书中的一些小知识点,这些知识点对于学习理解iOS系统有一定的帮助,不过若以后转向swift可能没有太多用处。
此处文章先hold住,慢慢补充

多用块枚举,少用for循环。
可以使用__bridge方式在Foundation框架中得Objective-C对象和CoreFoundation中得C数据结构进行转换。
使用缓存用NSCache不用NSDictionary,因为其会自己维护一个缓存淘汰算法,淘汰最久未使用的对象。而且NSCache是线程安全的。这里有个NSPurgeableData类型比较有意思,是NSMutableData的子类,和NSCache联合使用可以在NSPurgeableData内存释放时候自动清除缓存。
load方法:对于运行期系统的每个类(class)及分类(category),都必调用且仅调用一次。

基本调用顺序就是,执行当前类的load方法,必定先调用super的load方法,如果代码依赖其他程序库,那么程序库中得相关类的load方法也会先执行。类load方法执行完成后,会执行相应的分类的load的方法。

但是如果在一个程序库中得若干个class,却没法确定load顺序,所以load方法不建议使用其他class。

load方法在调用的时候,app会阻塞,所以一定要轻!

应用程序会阻塞并把所有类的load方法都执行完,才能继续。

load方法直接使用函数内存地址的方式(*load_method)(cls, SEL_load)调用的,而不是使用发送消息 objc_msgSend 的方式。

因此:load方法不遵循继承规则:如果一个class本身没有实现load方法,那么无论其各级super是否实现load,都不会调用;

同时:当一个类和它的分类都实现了 +load 方法时,两个方法都会被调用。

所以:像method swizzling这种操作会放在load里面进行。

load方法调用时,程序甚至没有autoreleasepool

initialize方法:首次使用该class前调用,且只有1次。

和load方法相比,他是“lazy”调用的,也就是类或它的子类收到第一条消息之前被调用的,这里所指的消息包括实例方法和类方法的调用。。

可以安全使用任何class,因为它们都已经load过了。

initialize方法执行一定在thread-safe environment,也就是说会阻塞所有线程。
initialize会走和objc_msgSend一样的消息发送原则,也就是会有覆盖。
实际编译器调用时,父类的会优先于子类调用。

相关load和initialize比较了解参考了以下博文:

Objective-C +load vs +initialize

Objective-C类初始化:load与initialize

iOS初探+load和+initialize

NSTimer的一些注意点

  • NSTimer一定要加入到runloop才有意义,如果没有addrunloop,那就加入到当前线程的runloop中,而子线程默认runloop没有run起来。
  • NSTimer的执行会持有target对象(因为一定是要target在一定时间调用其selector),这种持有会保持到失效为止,所以一定要注意针对repeating timer的循环引用问题。
  • 针对可能的循环引用问题,可以为NSTimer增加category,对实现增加block的实现方式。在调用时候只要注意一些block的内存使用问题就好了。