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

2019-02-19  本文已影响2人  _桃夭大人_

第五章 内存管理

第二十九条:理解引用计数

一般调用完release之后都会清空指针,这样就能保证不会出现“悬挂指针”(指向无效对象的指针)。

NSNumber * number = [[NSNumber alloc] initWithInt:123];
[number release];
number = nil;
- (void)setFoo:(id)foo{
    [foo retain];
    [_foo release];
    _foo = foo;
}

*自动释放池
autorelease 此方法会在稍后递减计数,通常是下一次“事件循环”时递减

- (NSString *)stringVaule{
     NSString * str = [[NSString alloc] initWithFormat:@"haha"];
return [str autorelease];
// autorelease能延长对象生命周期,使其在跨越方法调用边界后 依然可以存活一段时间。
}

*保留环
呈环状 相互引用的对个对象。导致内存泄漏。
解决方法:
(1)“弱引用”;
(2)令循环中的某个对象不再保留另一个对象;

  • 引用计数机制 通过可以递增递减的计数器来管理内存。

对象创建好之后,其保留计数至少为1,若保留计数为正,则对象存活,为0对象就被销毁了。

  • 在对象生命期中,其余对象通过引用来保留或者释放此对象。保留与释放操作分别会递增递减保留计数。

第三十条 :以ARC 简化引用计数

ARC会用一种安全的方式来设置:先保留新值,在释放旧值,最后设置啊实例变量。

- (void)setup{
    id tmp = [EOCOtherClass new];
    _object = [tmp retain];
    [tmp release];
}

第三十一条:在dealloc方法中只释放引用并解除监听

执行异步任务的方法不应该在dealloc里调用;只能在正常状态下执行的那些方法也不应该在dealloc里调用,因为此时对象已经处于正在回收的状态了。

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

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

image.png

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

Objective-C对象的生命周期取决于 其引用计数。
释放对象的两种方式:
(1)release 引用计数减一。
(2)autorelease 在稍后某个时刻释放对象。

// 创建自动释放池(轻量级)
@autoreleasepool{
// ... 
}

系统会自动创建一些线程,比如主线程和GCD机制中线程,这些线程默认都有自动释放池,每次执行“事件循环”时,就会将其清空。

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

向已经回收的对象发送消息是不安全的,取决于 对象所占内存有没有为其他内容所覆写。

运行期系统会把所有已经回收的实例转化为特殊的“僵尸对象”,而且不会真正回收他们。
“僵尸对象”所在的 核心内存 无法重用,因此不能覆写。僵尸对象收到消息后,会抛出异常。

将 NSZombieEnabled环境变量 设为YES 开启“僵尸对象”功能。

第三十六条:不要使用retainCount

retainCount 是NSObject协议中定义的方法,用于查询对象当前的保留计数。ARC废弃了。
此方法无用的原因:
(1)它所返回的保留计数只是某个给定时间点上的值。未考虑到系统稍后会把自动释放池清空。
(2)retainCount 可能永远不返回0,

上一篇下一篇

猜你喜欢

热点阅读