第29条:理解引用计数

自动引用计数(Automatic Reference Counting, ARC

垃圾收集器:

从Mac OS X 10.8开始,“垃圾收集器”(gargae collector)已经正式废弃了。

每个对象都有个计数器,用以表示当前有多少个事物想令此对象继续存活下去。叫做“保留计数”(retain count),也可以叫“引用计数”(reference count)。

由三个方法操作计数器

reatain 递增

release 递减

autorelease 递减,自动释放池(autorelease pool,第34条)

查看保留计数的方法:retainCount, 不推荐使用。

对象创建出来时,其保留计数至少为1。

当保留计数为零时,对象就回收了(deallocated),也就是说,系统会将其占用的内存标记为“可重用”(reuse)。

内存在“解除分配”(deallocated)之后,只是放回“可用内存池”(avaiable pool)。如果该内存没有覆写,那么对象仍然有效,这时程序不会崩溃。

为避免在不经意间使用了无效对象,一般调用完饭release之后都会清空指针。这时就能保证不会出现可能指向无效对象的指针,这种指针通常称为“悬挂指针”(dangling pointer,野指针)。

例:

  [xxxx release];

  xxxx = nil;

对象如果持有指向其他对象的强引用(strong reference),那么前者就“拥有”(own)后者。

引用的“根对象”

MAC OS X应用程序中,NSApplication对象

iOS应用程序中,UIApplication对象。

两者都应用程序启动时创建的单例。

属性存取方法中的内存管理

例:

-(void)setFoo:(id)foo {

  // [foo retain]; // 先保留新值

  // [_foo release]; // 再释放旧值

  // _foo = foo; // 更新实例变量,令其指向新值

  [_foo release];

  _foo = [foo retain];

}

顺序很重要。

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

自动释放池:

autorelease,此方法会在稍后递减计数,通常是在下一次“事件循环”(event loop)时递减,不过也可能执行地更早些(自己创建的自动释放池)。

autorelease能延长对象生命期,使其在跨越方法调用边界后依然可以在存活一段时间。

一般用于方法中返回对象时。

例:

-(NSString *)stringValue {

  NSString *str = [NSString alloc]initWithFormat:@"%@",self];

  retrun [str autorelease];

}

保留环(retain cycle):

循环引用,无法释放

1、通常采用“弱引用”(weak reference,参见第33条)

2、或者从外界命令(???循环中的某个对象不再保留另外一个对象。

这两种方法都可以打破保留环,从而避免内存泄漏。

时间: 2024-10-13 08:30:31

第29条:理解引用计数的相关文章

第29条:理解引用计数

第5章 内存管理 在 Objective-C 这种面向对象语言里,内存管理是个重要概念.要想一门语言写出内存使用效率高而且又没有 bug 的代码,就得掌握其内存管理模型的种种细节. 一旦理解了这些规则,你就会发现,其实 Objective-C 的内存管理没那么复杂,而且有了 "自动引用计数"(Automatic Reference Counting, ARC)之后,就变得更为简单了.ARC 几乎把所有内存管理事宜都交由编译器来决定,开发者只需专注于业务逻辑. 本条要点:(作者总结) O

iOS 理解引用计数

一 简介     OC 语言使用引用计数来管理内存每个对象都有个可以递增或递减的计数器,如果想某个对象继续存活,那就递增其引用计数,用完之后,就递减其计数,计数变为0,就销毁. 二 引用计数工作原理 NSObject 协议声明了下面三个方法用于操作计数器,以递增或递减其值 retain 递增引用计数 release 递减引用计数 autorelease 稍后清理"自动释放池"时,在递减引用计数 为避免在不经意间使用了无效对象,一般调用完release 之后都会清空指针.这就能保证不会出

Objective-C内存管理之引用计数

初学者在学习Objective-c的时候,很容易在内存管理这一部分陷入混乱状态,很大一部分原因是没有弄清楚引用计数的原理,搞不明白对象的引用数量,这样就当然无法彻底释放对象的内存了,苹果官方文档在内存管理这一部分说的非常简单,只有三条准则: 当你使用new.alloc或copy方法创建一个对象时,该对象的保留指针为1,当不再使用该对象的时候,你应该想该对象发送一条release或autorelease消息,这样,该对象在其寿命结束时将被销毁. 当你通过其他方法获得一个对象时,假设该对象的保留计数

第30条:以ARC简化引用计数

本条要点:(作者总结) 引用计数这个概念相当容易理解.需要执行保留与释放操作的地方也很容易就能看出来.所以 Clang 编译器项目带有一个 "静态分析器"(static analyzer).用于指明程序里引用计数出问题的地方.举个例子,假设下面这段代码采用手工方式管理引用计数: 1 if ([self shouldLogMessage]) { 2 3 NSString *message = [[NSString alloc] initWithFormat:@"I am obj

深入理解 PHP7 中全新的 zval 容器和引用计数机制

深入理解 PHP7 中全新的 zval 容器和引用计数机制 最近在查阅 PHP7 垃圾回收的资料的时候,网上的一些代码示例在本地环境下运行时出现了不同的结果,使我一度非常迷惑. 仔细一想不难发现问题所在:这些文章大多是 PHP5.x 时代的,而 PHP7 发布后,采用了新的 zval 结构,相关的资料也比较贫瘠,所以我结合一些资料做了一个总结, 主要侧重于解释新 zval 容器中的引用计数机制 ,如有谬误,还望不吝指教. PHP7 中新的 zval 结构 明人不说暗话,先看代码! struct 

OSG下的引用计数指针(Reference Pointers)的理解

使用OpenSceneGraph会经常见到这样的代码 osg::ref_ptr<osg::Node> nodeRptr = new osg::Node; osg::ref_ptr即为Reference counted objects 每次使用时自动递增,用完后自动递减,当最后一个 计数器变为0,对象自动销毁. ref_ptr模板类型继承自Referenced类,Referenced类有三个基本函数: void ref()增加引用计数 void unref()减少引用计数 int getRefe

swift详解之九---------------自动引用计数、循环引用

自动引用计数.循环引用(这个必须理解,必须看) 注:本文详细介绍自动引用计数,以及各种循环引用问题.一网打尽! 1. 自动引用计数原理 Swift 使用ARC机制来跟踪和管理你的内存,一般情况下,Swift 的内存管理机制会一直起着作用,你无须自己来考虑内存的管理.ARC 会在类的实例不再被使用时,自动释放其占用的内存. 然而,在少数情况下,ARC 为了能帮助你管理内存,需要更多的关于你的代码之间关系的信息.本章描述了这些情况,并且为你示范怎样启用 ARC 来管理你的应用程序的内存. 为了确保在

进击的雨燕--------------自动引用计数

Swift 使用自动引用计数(ARC)机制来跟踪和管理你的应用程序的内存.通常情况下,Swift 内存管理机制会一直起作用,你无须自己来考虑内存的管理.ARC 会在类的实例不再被使用时,自动释放其占用的内存. 然而,在少数情况下,ARC 为了能帮助你管理内存,需要更多的关于你的代码之间关系的信息.本章描述了这些情况,并且为你示范怎样启用 ARC 来管理你的应用程序的内存. 注意:引用计数仅仅应用于类的实例.结构体和枚举类型是值类型,不是引用类型,也不是通过引用的方式存储和传递. 自动引用计数的工

自动引用计数

http://numbbbbb.gitbooks.io/-the-swift-programming-language-/content/chapter2/16_Automatic_Reference_Counting.html 本页包含内容: 自动引用计数的工作机制 自动引用计数实践 类实例之间的循环强引用 解决实例之间的循环强引用 闭包引起的循环强引用 解决闭包引起的循环强引用 Swift 使用自动引用计数(ARC)这一机制来跟踪和管理你的应用程序的内存.通常情况下,Swift 的内存管理机