Effective Objective-C 2.0读书笔记(六)

第31条,在dealloc 方法中只释放引用并解除监听

  • 在每个对象的生命周期内,dealloc方法只执行一次,就是保留计数为0 的时候,何时执行无法保证。
  • dealloc方法中主要做的操作是释放对象所拥有的引用。
  • dealloc方法中需要把原来的观测行为清理掉,比如通知(NSNotificationCenter)的移除。
  • 开销较大或者系统内稀缺的资源不在dealloc的释放范围内,这些需要自身手动释放,其中包括:文件描述符(file descriptor)、套接字(socket)、大块内存。
  • 在dealloc里不要随便调用其他方法,也不要执行异步操作,系统释放后,有可能导致程序出错。
  • dealloc中不要调用属性的存取方法,因为属性可能处于键值观测机制下,属性的观察者在属性值改变的时候有可能保留即将回收的对象,导致释放不顺,引起错误。

关键词:dealloc、NSNotification、键值观测(KVO)

第32条,编写“异常安全代码”时留意内存管理问题

  • OC的错误模型里,只有严重错误的时候,异常才会发生。
  • 捕获异常时,一定要注意将try块所创立的对象清理干净。
  • 默认情况下,ARC不生成安全处理异常所需的清理代码,开启编译器标志后,可生成这种代码,不过会导致应用程序变大,而且降低运行效率。

关键词:ARC异常处理、异常安全

第33条,以弱引用避免保留环

  • 保留环的引起条件:OC内存管理是引用计数,两个及以上的对象相互引用就会导致形成一个“环”,无法正常释放内存。
  • Mac OS X平台的OC有个选项,可以启动垃圾收集器,它会检测保留环,发现外界不再引用其中对象就会回收,Mac OS X 10.8开始,垃圾回收机制被废弃,在iOS中没有此项功能。
  • 避免保留环的最佳方式就是弱引用。

关键词:保留环、弱引用

第34条,以“自动释放池”降低内存峰值

  • 自动释放池用户存放那些需要在稍后某个时刻释放的对象。
  • 主线程和GCD中默认都有自动释放池,每次执行完事件循环时,会清空处理。
  • 自动释放池的格式:@autoreleasepool {}
  • 自动释放池可以嵌套使用,在嵌套中,系统自动释放对象时,会把它放到最内层的池里。
  • 在for循环中,如果有临时变量的存在,适合用自动释放池,可以降低内存峰值。
  • 在必要的情况下使用自动释放池,以减小不必要的额外开销。

关键词:自动释放池、autoreleasepool、循环下的临时变量

第35条,用“僵尸对象”调试内存管理问题

  • 向已回收的对象发送消息是不安全的。
  • 僵尸对象机制就是把已经回收的对象转化成僵尸对象,当接到消息时,会带上“僵尸”标记,用来调试内存管理问题。
  • 给僵尸对象发送消息,控制台会打印消息,应用程序会终止。
  • 系统给每个变成僵尸的类创建一个对应的新类,是为了能够知道该对象原来所属的类。
  • 系统会修改对象的isa指针,令其指向特殊的僵尸类,从而使该对象变为僵尸对象,僵尸类能够响应所有的选择子,响应方式为:打印一条包含消息内容及其接受者的消息,然后终止应用程序。

关键词:僵尸对象、已回收的对象、内存管理

第36条,不要使用 retainCount

  • ARC下retainCount方法被废弃了,因为获取的数是不准确的,ARC模式下调用retainCount方法会报错。
  • 对象的保留计数没有绝对的计数,任何时间获取的数,只能反应局部状态,不能反应全貌。

关键词:retainCount

原文地址:https://www.cnblogs.com/akiha/p/13267679.html