`
janedoneway
  • 浏览: 570446 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Cocoa对象的生命周期

 
阅读更多

From: http://www.apple.com.cn/developer/mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/chapter_3_section_5.html#//apple_ref/doc/uid/TP40002974-CH4-SW10

 

 

Cocoa对象的生命周期(至少是潜在地)跨越不同的阶段。它需要被创建、初始化、和使用(就是其它对象向它发送消息),它可能被保持、拷贝、或者归档,并最终被释放和销毁。下面的讨论将给出一个典型对象的生命周期框图,但仍然不涉及太多的细节。

让我们从最后开始,即从清理对象的方式开始讨论。和其它编程语言不同,Objective-C没有自动释放不再使用的对象的“垃圾收集”设施。垃圾收集开销大而且不灵活,取而代之的是,Cocoa和Objective-C选择一种主动的、策略驱动的例程来保持对象,并在不再需要的时候进行清理。

这种例程和策略建立在引用计数的基础上。每个Cocoa对象都带有一个整数,用于指示对其持久性感兴趣的其它对象(甚至是例程代码的现场)的数目。这个整数被称为对象的保持数(“保持” 是为了避免和“引用”重复)。当您通过alloc或者allocWithZone:类方法创建对象的时候,Cocoa做了一些非常重要的工作:

  • 它将对象的isa指针—NSObject类中唯一的公共实例变量—指向对象的类,因此将对象集成到类层次的运行时视图中(进一步信息请参见"对象的创建"部分)。

  • 它将对象的保持数—一个隐藏的实例变量,所有对象都有—设置为1(这里假定对象的创建者对其持久性感兴趣)。

对象分配内存之后,您通常需要将其实例变量设置为合理的初始值,以便进行初始化(NSObject声明了init方法作为这个目的的原型)。这样对象就可以使用了,您可以向它发送消息,将它传递给其它对象,等等。

请注意:由于除了显式分配的对象之外,初始化方法也可以返回一个对象,因此习惯上将alloc消息嵌套在init消息(或其它初始化方法)中—举例来说:

id anObj = [[MyClass alloc] init];

 

当您释放一个对象—也就是向对象发送一个release消息时—NSObject会减少它的保持数。如果保持数从1下降到0,对象就会被解除分配。对象的解除分配有两个步骤:首先是对象的dealloc方法被调用,以释放实例变量和动态分配的内存;然后是操作系统将对象的本身销毁,并回收对象占用的内存。

重要提示:您永远不应该直接调用对象的dealloc方法。

 

如果您不希望对象很快消失,该怎么办呢?如果您在创建对象之后向它发送一个retain消息,对象的保持数就会增加到2。这样,就需要两个release消息才能导致对象的释放。图2-3描述了这种极为简单的场景。

图 2-3 对象的生命周期—简化视图

The life cycle of an object?simplified view

 

当然,在这个场景下,对象的创建者不需要保持对象,它已经拥有对象了。但是,如果这个创建者要将对象传递给消息中的另一个对象,则情况就不一样了。在Objective-C程序中,人们假定从其它对象接收到的对象在其被得到的作用域内总是正当的。负责接收的对象可以向被接收的对象发送消息,而且可以将它传递给其它对象。这个假设要求对象的发送者“行为规矩”,不要在客户对象仍然拥有被发送对象的引用时将它过早释放。

如果客户对象在程序的作用域之外希望保持接收到的对象,则可以保持该对象—也就是向它发送一个retain消息。保持一个对象会增加该对象的保持数,从而表示希望拥有该对象。客户对象有责任在一段时间后释放该对象。如果对象的创建者将该对象释放,但同时有一个客户对象已经保持了该对象,则该对象会一直持续到客户对象将它释放为止。图2-4说明了这个序列:

图2-4 保持接收到的对象

Retaining a received object

 

您可以不保持对象,而是通过发送copycopyWithZone:消息来对其进行拷贝(很多子类—如果不是大多数的话—都封装了某种数据采纳方法,或遵循这种协议)。拷贝一个对象不仅仅是对其进行复制,而且几乎总是将它的保持数设置为1(请参见图2-5)。根据对象的本质和可能的用法,拷贝可以是浅拷贝,也可以是深拷贝。深拷贝将对象复制为被拷贝对象的一个实例变量,而浅拷贝只是复制那些实例对象的引用。

在用法方面,copyretain的区别在于前者要求成为对象新的、唯一的拥有者;新的拥有者可以修改拷贝后的对象,而不考虑其原始对象。一般地说,您需要对值对象(即对某些简单的值进行封装的对象)进行拷贝,而不是保持。特别是当对象是可变的时候,比如一个NSMutableString对象。对于不可变对象,copyretain可能是等价的,其实现方法也是类似的。

 

图2-5 拷贝接收到的对象

Copying a received object

 

您可能已经注意到,用这种策略管理对象的生命周期有一个潜在的问题,就是创建一个对象并将它传递给另一个对象的对象本身并不总是知道什么时候可以安全地释放对象。在调用堆栈中可能有多个该对象的引用,某些引用可能来自创建者不知道的对象。如果创建者对象释放了其所创建的对象,而其它对象向这个已经被销毁的对象发送消息,程序就会崩溃。为了解决这个问题,Cocoa引入了一种延迟对象释放的机制,称为自动释放(autoreleasing)机制。

自动释放机制通过自动释放池(由NSAutoreleasePool类定义)来实现。自动释放池是位于显式定义的作用域内的一个对象集合,该作用域被标志为最后释放。自动释放池可以嵌套。当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放(参见图2-6)。如果您正在开发应用程序,可能不需要建立一个自动释放池,Application Kit会自动建立一个自动释放池,其作用域为为应用程序的事件周期。

 

图2-6 自动释放池

An autorelease pool

 

到目前为止,对象生命周期的讨论主要关注整个周期中的对象管理机制。但是,指导如何使用这些机制的是对象的所有权策略。这个策略可以概括如下:

  • 如果您通过分配和初始化(比如[[MyClass alloc] init])的方式来创建对象,您就拥有这个对象,需要负责该对象的释放。这个规则在使用NSObject的便利方法new时也同样适用。

  • 如果您拷贝一个对象,您也拥有拷贝得到的对象,需要负责该对象的释放。

  • 如果您保持一个对象,您就部分拥有这个对象,需要在不再使用时释放该对象。

反过来,

  • 如果您从其它对象那里接收到一个对象,则您不拥有该对象,也不应该释放它(这个规则有少数的例外,在参考文档中有显式的说明)。

和其它规则一样,这些策略也有一些例外和经常出错的地方:

  • 如果您通过类工厂方法来创建对象(比如NSMutableArray arrayWithCapacity:方法),则可以假定您接收到的对象已经自动被放到自动释放池了。您不应该自行将它释放,如果您需要保持该对象,则应该保持(retain)它。

  • 为了避免循环引用,子对象不能保持它的父对象(父对象是该子对象的创建者,或者将该子对象作为实例变量持有的对象)。

请注意:在上面的原则中提到的“释放”是指向对象发送一个releaseautorelease消息。

 

如果您没有遵循这个所有权的策略,则可能导致您的Cocoa程序出现两种不好的结果:由于没有释放自己创建、拷贝、或保持的对象,您的程序会发生内存泄露;或者,由于向已经解除分配的对象发送消息,您的程序发生崩溃。而且还会有进一步的问题:调试这些问题可能相当费时间。

对象的生命周期中可能发生的另一个基本事件是归档。归档是将组成一个面向对象程序中的相关对象形成的网状结构—对象图—转化为一种可持久的形式(通常是一个文件),该形式可以保存对象图中对象的标识和彼此之间的关系。在解档时,可以通过这个档案重新构造出程序的对象图。为了参与归档(和解档),对象必须支持通过NSCoder类定义的方法对实例变量进行编码(和解码)。为了这个目的,NSObject采纳了NSCoding协议。有关对象归档的更多信息,请参见"对象的归档"部分。

分享到:
评论

相关推荐

    深度解析iOS应用程序的生命周期

    iOS应用程序一般都是由自己编写的代码和系统框架(systemframeworks)组成,系统框架提供一些基本infrastructure给所有App来运行,而你提供自己编写的代码来定制App的外观和行为。因此,了解iOSInfrastructure和它们...

    cocoa基本原理指南

    Cocoa对象的常见行为、接口、和生命周期。 3. "为Cocoa程序添加行为" 描述如何使用Cocoa框架来编写程 序,解释如何创建一个子类。 4. "Cocoa的设计模式" 描述Cocoa采纳的设计模式,特别是模 型-视-控制器对象模型。 5...

    Cocoa基本原理指南(2010年4月16日).zip

    Cocoa对象的常见行为、接口、和生命周期。 3. "为Cocoa程序添加行为" 描述如何使用Cocoa框架来编写程 序,解释如何创建一个子类。 4. "Cocoa的设计模式" 描述Cocoa采纳的设计模式,特别是模 型-视-控制器对象模型。 ...

    Cocoa 基本原理指南.pdf (中文)

    对于刚刚加入这个阵营的开发者来说, Cocoa像是一个巨大而未知的新世界。Cocoa开发环 境的各种特性、工具、概念、术语、编程接口、甚至是编程语言对他们来说可能都比较生 疏。 Cocoa基本原理指南提供了领略Cocoa...

    Cocoa 是什么?

    对于刚刚加入这个阵营的开发者来说,Cocoa 像是一个巨大而未知的新世界。Cocoa 开发环境的各种特性、工具、概念、术语、编程接口、甚至是编程语言对他们来说可能都比较生疏。Cocoa 基本原理指南提供了领略Cocoa 技术...

    Cocoa和CocoaTouch的模型框架Mantle.zip

    Mantle 是 Cocoa 和 Cocoa Touch 的模型框架,你可以通过它为你的 Cocoa 和 Cocoa Touch 写简单的模型层。示例代码:@interface XYUser : MTLModel @property (readonly, nonatomic, copy) NSString *name;...

    Cocoa基本原理指南(Cocoa Fundamentals Guide)

    Cocoa Fundamentals Guide 的中文版

    Cocoa入门 使用Objective-C 第二版70m

    介绍完Xcode和Interface Builder之后,您将很快接触到Objective-C的面向对象编程概念,它是创建Mac OS X应用程序的首选语言。每章中都提供了不同的示例程序供您构建,通过循序渐进的指导来教给您Cocoa编程的基础。每...

    Cocoa Programming Developers Handbook(PDF and Source Code)

    Cocoa Programming Developer’s Handbook 书籍以及配套源码 对应的中文译本名《Cocoa编程开发者手册》,这里提供的是其原本,技术人员建议还是读原本。 《Cocoa编程开发者手册》是关于MacOSX上CocoaAPI的指南,...

    Cocoa基础指南介绍

    从官网复制的iOS开发参考文献:Cocoa基础指南介绍

    [Cocoa] Cocoa Objective-C 开发学习手册 第4版 (英文版)

    [奥莱理] Cocoa Objective-C 开发学习手册 第4版 (英文版) [奥莱理] Learning Cocoa with Objective-C 4th Edition (E-Book) ☆ 图书概要:☆ You’ll learn how to work with the Xcode IDE, Objective-C’s ...

    Cocoa Design Patterns 2018

    Cocoa Design Patterns.pdf Cocoa Design Patterns.pdf

    iOS and macOS Performance Tuning Cocoa, Cocoa Touch, Objective-C, and Swift

    iOS 和 macOS 性能优化书。iOS and macOS Performance Tuning Cocoa, Cocoa Touch, Objective-C, and Swift

    cocoa编程之菜鸟入门

    这本书手把手教你使用xcode开发cocoa程序,菜鸟必备

    iphone cocoa 2d游戏开发

    cocoa 2d 游戏开发 iphone iOS cocoa2d 游戏 ipad

    Learning Cocoa With Objective-C

    Cocoa编程经典的入门书籍,图文讲解,易于学习

    Cocoa开发者手册样张

    cocoa开发者手册是本经典的cocoa开发教程,主要帮助读者理清开发中常用的API,不适合初学cocoa开发的人员

    Learn Cocoa on the Mac, 2nd Edition

    The key to creating a modern Mac application is Cocoa. According to Apple, Cocoa is a set of object-oriented frameworks that provide a runtime environment for Mac OS X applications. As you make your ...

    cocoa design patterns.pdf

    cocoa 设计模式 英文版,本书介绍了 cocoa 的基本设计模式,以 MVC 为基础,有助于更好地理解 cocoa 框架

    [Cocoa]_[NSTableView]_[基本使用]

    Cocoa下NSTableView的简单使用

Global site tag (gtag.js) - Google Analytics