《Effective Objective-C 2.0》读书笔记(

2019-04-08  本文已影响0人  KeyboardDirver

第五章 内存管理

第29条:理解引用计数

OC 中有手动内存管理(MRC) 自动内存管理(ARC)
手动内存管理需要程序员亲自操作对象的的释放,而ARC中就免除了繁琐的release操作。但是在iOS中不是所有对象都无需手动释放的,比如非OC(比如C语言创建的)中的对象需要手动释放,不然会存在内存泄漏的风险。

//比如使用#import <VideoToolbox/VideoToolbox.h> 
CVPixelBufferRef  outputPixelBuffer = NULL;
outputPixelBuffer ........
CFRelease(outputPixelBuffer);

retain count叫做“保留计数”也可以叫做“引用计数”。
NSObject 协议声明了下面三个方法用于操作计数器,以递增或递减其值:

MRC下的set方法

-  (void)setFoo:(id)foo{
  [foo retain];
  [_foo release];
  _foo = foo;
}

这个顺序很重要。加入还未保留新值就报旧值释放了,而且两个值又指向同一个对象,那么,先执行的release操作就可能导致系统将此对象永久回收。而后续的retain操作则无法令这个已经彻底回收的对象复生,于是实例变量就成了悬挂指针(野指针,僵尸对象)。

自动释放池
autorelease 会在稍后递减计数,通常是下一次“时间循环(event Loop)”时递减,不过也也可能执行的更早。此特性在方法中返回兑现时更该用它。

//MRC下的返回值方法
-  (NSString *)stringValue{
    NSString * str = [[NSString alloc] initWithFormat:@"I am this: %@",self];
    return [str autorelease];
}

保留环 (retain cycle)
每个对象都相互引用着对方,使用“弱引用”可以打破这种状态。或是从外界命令循环中的某个对象不在保留另外一个对象。从而避免内存泄漏

要点

第30条:以ARC简化引用计数
  clang编译器项目垈有一个“静态分析器”(static analyzer),用于指明程序里引用计数出问题的地方。
   使用ARC时一定要记住,引用计数实际上还是要执行的,只不过保留与释放操作现在是由ARC自动为你添加。
    ARC调用方法时,并不通过普通的Object-C消息派发机制,而是直接调用底层C语言版本。这样做性能更好。

使用ARC时必须遵循的方法命名规则。
将内存管理语意在方法名重表示出来早已成为Object-C的惯例,而ARC则将之确立为硬性硬性规定。若方法名以下列词语开头,则其返回的对象归调用者所有:

- (void)dealloc{
    CFRelease(_coreFoundationObject);
    free(_heapAllocatedMemoryBlob);
}

要点

第31条:在dealloc方法中只释放引用并解除监听
  对象在经历其生命周期后,最终会为系统所回收,这时就要执行dealloc方法了,在每个对象的生命周期内,此方法仅执行一次,也就是当保留计数将为0的时候,具体何时执行无法确定。

要点

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

要点

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

最简单的保留环由两个对象组成。如果没有别的对象可以引用环中的对象导致这个环无法被访问,他们就会继续存活下去,造成内存泄漏。
要点

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

整理要理清自动释放池的原理和自动释放池与runloop的关系
线程、自动释放池、RunLoop的爱恨情仇
探究自动释放池的实现

要点

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

要点

第36条:不要使用retainCount

要点

上一篇 下一篇

猜你喜欢

热点阅读