`
mmdev
  • 浏览: 12944275 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Objective-C内存管理编程指南(7)Cocoa 中 Core Foundation 对象的内存管理和Nib 对象的内存管理

 
阅读更多

Cocoa Core Foundation 对象的内存管理

许多Core Foundation对象和Cocoa实例可以简单地相互进行类型转换,比如CFStringNSString对象。本文介绍如何管理Cocoa中的Core Foundation对象。有关对象所有权的一般信息请参考对象的所有权和销毁

重要:本章介绍了CocoaCore Foundation对象在引用计数环境中的用法。如果您使用垃圾回收机制垃圾回收编程指南,则语义有所不同。

Core Foundation对象的内存分配策略是,您需要释放那些由名字中包含“Copy”“Create”的函数返回的值;您不应该释放那些由名字中不包含“Copy”“Create”的函数返回的值。

Core Foundation对象和Cocoa使用的公约非常相似,而且由于分配(allocation/保留(retain/释放(release)的实现是兼容的每种环境中等价的函数和方法可以混合使用。因此,

NSString *str = [[NSString alloc] initWithCharacters: ...];

...

[str release];

等同于

CFStringRef str = CFStringCreateWithCharacters(...);

...

CFRelease(str);

NSString *str = (NSString *)CFStringCreateWithCharacters(...);

...

[str release];

NSString *str = (NSString *)CFStringCreateWithCharacters(...);

...

[str autorelease];

正如这些代码示例所示,一旦被创建,类型转换对象可以被视为CocoaCore Foundation对象,而且,在每种环境中看起来都是本地的。

Nib 对象的内存管理

Cocoa应用程序运行时生命周期中,会有一个或多个nib文件被加载,而且它们所包含的对象会被解压。当不再需要它们时,谁来负责释放这些对象取决于您在哪种平台进行开发,而且,如果是在Mac OS X的话,还取决于您的File’s Owner继承自哪个类。

关于nib文件及其内存管理语义的基本讨论,以及与nib相关的术语的定义,比如插座对象,File’s Owner和顶层对象,请参考资源编程指南中的“Nib文件一节。

插座对象

当一个nib文件被加载且插座对象被建立的时候,如果存取方法(在Mac OS XiOS上都)存在,则nib加载机制一定会使用存取方法。因此,无论您在哪个平台上进行开发,一般情况下,您都应该使用Objective-C属性声明功能声明插座对象。

声明插座对象的一般形式应该是:

@property (attributes) IBOutlet UserInterfaceElementClass *anOutlet;

插座对象的行为取决于平台的类型(请参考“MacOSX”“iOS”),因此,实际的声明会有所不同:

§ 对于MacOSX,您应该使用:

@property (assign) IBOutlet UserInterfaceElementClass *anOutlet;

§ 对于iOS,您应该使用:

@property (nonatomic, retain) IBOutlet UIUserInterfaceElementClass *anOutlet;

接下来,您应该做的是合成相应的存取方法,或者是根据声明实现这些方法,(在iOS平台)还要在dealloc中释放相应的变量。

如果您使用现代运行时并合成实例变量,这种模式同样适用,因此它能够在所有情况下保持一致性。

MacOSX

在默认情况下,nib文件的File’s Owner负责释放nib文件中的顶层对象和nib中的对象创建的所有非对象资源。对象图中的根对象的释放会促使所有依赖它的对象也被释放。对应用程序的主nib文件(其中包含应用程序菜单和其他可能的项目)来说,它的文件所有者是全局应用程序对象NSApp。然而,当Cocoa应用程序终止时,主nib中的顶层对象不会因为NSApp被回收(请参考回收对象)而自动获得dealloc消息。换句话说,即使是在主nib文件中,您也必须管理顶层对象的内存。

应用程序套件提供了一系列功能来帮助您确保nib对象能够被正确地释放:

§ NSWindow对象(包括面板)有一项isReleasedWhenClosed属性,如果该属性被设为YES,则窗口会在关闭的时候释放它自己(和它的视图层次中所有相关的对象)。在Interface Builder中,您可以通过勾选检视器的属性面板上的在关闭时释放复选框来设置此选项。

§ 如果nib文件的文件所有者是一个NSWindowController对象(它是基于文档的应用程序中的文档默认nib—前面介绍过,NSDocument负责管理NSWindowController实例),它会自动销毁它所管理的窗口。

因此,在一般情况下,您负责释放nib文件中的顶层对象。但实际上,如果您的nib文件的所有者是一个NSWindowController实例,则它会为您释放顶层对象。如果您的某个对象加载了nib本身(而且它的所有者不是NSWindowController实例),则您可以为每一个顶层对象定义插座对象,以便您可以在适当的时候使用这些引用释放它们。如果您不希望为所有的顶层对象定义插座对象,那么您可以使用NSNib类的instantiateNibWithOwner:topLevelObjects:方法来获得一个包含nib文件顶层对象的数组。

当您考虑到应用程序的各种类型时,销毁nib对象的责任问题就变得更清晰了。大多数Cocoa应用程序归属于两类:单一窗口应用程序和基于文档的应用程序。在这两种情况下,系统会在一定程度上为您自动处理nib对象的内存管理。在单一窗口应用程序中,主nib文件中的对象在应用程序的整个运行周期内持续存在,并在应用程序终止时被释放;但是,系统并不保证在应用程序终止时自动地对主nib文件中的对象调用dealloc。在基于文档的应用程序中,每一个文档窗口都由一个NSWindowController对象管理,该对象处理文档nib文件的内存管理。

有些应用程序可能具有更复杂的nib文件和顶层对象的分布。例如,应用程序可能有多个nib文件,并带有多个窗口控制器,可加载的面板和检视器。但是,在大多数情况下,如果您使用NSWindowController对象来管理窗口和面板,或者如果您设置了在关闭时释放这一窗口属性,那么系统会为您自动处理大部分的内存管理。如果您决定不使用窗口控制器,也不想设置在关闭时释放属性,则您应该在窗口关闭时显式地释放您的nib文件的窗口和其他顶层对象。此外,如果您的应用程序使用检视器面板,那么(在延迟加载之后)该面板通常应该在整个应用程序生命周期内持续存在没有必要销毁检视器和它的资源。

iOS

顶层对象

nib文件中的对象被创建时,它们的保留计数为1,而且随后它们会被自动释放。由于重建了对象层次结构,UIKit会使用setValue:forKey:重新建立对象之间的连接,setValue:forKey:使用现有的setter方法,如果没有setter方法可用,那么它会默认保留这个对象。这就意味着(假设您遵循插座对象中所示的模式)具有插座对象的任何对象都保持有效。但是,如果存在您没有存储在插座对象中的顶层对象,则您必须保留loadNibNamed:owner:options:方法返回的数组或数组中的对象,以防止这些对象过早地被释放。.

内存警告

当视图控制器收到内存警告(didReceiveMemoryWarning)的时候,它应该释放那些当前不需要的,和那些如果有需要可以稍后重新创建的资源的所有权。其中一种资源就是视图控制器的视图本身。如果它没有父视图,则该视图应该被销毁(在它的didReceiveMemoryWarning实现中,UIViewController调用[self setView:nil])。

但是,由于nib文件中的元素的插座对象通常会被保留(见插座对象),因此,即使主视图被销毁,如果没有采取任何进一步的行动,插座对象也不会被销毁。这并不是其本身的问题如果当主视图被重新载入时,它们只是被简单地替换掉但这确实意味着,didReceiveMemoryWarning的效果被削弱了。为了确保您正确地释放插座对象的所有权,在您的自定义视图控制器类中,您可以实现viewDidUnload来调用您的存取方法,以便将插座对象设置为nil

- (void)viewDidUnload {
 self.anOutlet = nil;
 [super viewDidUnload];
}

注意:iOS 3.0版本之前,viewDidUnload方法是不可用的。相反,您应该在setView:中将插座对象设置为nil,正如该例所示:

- (void)setView:(UIView *)aView {
 if (!aView) { // View is being set to nil.
 // Set outlets to nil, e.g.
 self.anOutlet = nil;
 }
 // Invoke super's implementation last.
 [super setView:aView];
}

此外,由于UIViewController中的dealloc的一个实现细节,您还应该在dealloc中将插座对象变量设置为nil

- (void)dealloc {
 // Release outlets and set outlet variables to nil.
 [anOutlet release], anOutlet = nil;
 [super dealloc];
}
分享到:
评论

相关推荐

    Using Swift With Cocoa and Objective-C中文版

    Using Swift With Cocoa and Objective-C中文版,OC和Swift混合使用

    Objective-C基础教程+随书源代码

     本书全面而系统地讲述Objective-C语言的基础知识和面向对象编程的重要概念,结合实例介绍了Cocoa工具包的优秀特性和其中的框架,以及继承、复合、源文件组织、内存管理、对象初始化和类别创建等众多重要的面向对象...

    Cocoa and Objective-C

    Cocoa and Objective-C Cocoa and Objective-CCocoa and Objective-C Cocoa and Objective-C

    《内存管理编程指南》PDF

    内容:“内存管理规则”总结...“Cocoa 中 Core Foundation 对象的内存管理”介绍了Cocoa代码中Core Foundation对象的内存管理技术及使用指南。“Nib 对象的内存管理”讨论了与nib文件相关的内存管理的问题。pdf格式。

    Objective-C基础教程 中文 PDF 清晰版 [31M]

    本书结合理论知识与示例程序,全面而系统地讲述Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性和Cocoa工具包的功能及其中的框架,以及继承、复合、源文件组织等众多重要的面向对象编程技术。...

    Objective-C的语法与Cocoa框架.pdf

    Objective-C的语法与Cocoa框架.pdf,挺不错的教程

    iOS 7 Programming Fundamentals: Objective-C, Xcode, and Cocoa Basics

    iOS 7 Programming Fundamentals: Objective-C, Xcode, and Cocoa Basics by Matt Neuburg (Author) Publisher: O’Reilly Media (October 2013) Language: English ISBN-10: 1491945575 ISBN-13: 978-...

    Learning Cocoa With Objective-C

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

    《Objective-C2.0程序设计(原书第2版)》_中文完整版

    第二部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective-C的快速参考。 ...

    Objective-C基础教程

    《Objective-C基础教程》全面而系统地讲述Objective-C语言的基础知识和面向对象编程的重要概念,结合实例介绍了Cocoa工具包的优秀特性和其中的框架,以及继承、复合、源文件组织、内存管理、对象初始化和类别创建等...

    Objective-C基础教程(第2版).pdf

    本书结合理论知识与示例程序,全面而系统地讲述Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性和Cocoa工具包的功能及其中的框架,以及继承、复合、源文件组织等众多重要的面向对象编程技术。...

    Objective-C基础教程随书源码

    《Objective-C基础教程》全面而系统地讲述Objective-C语言的基础知识和面向对象编程的重要概念,结合实例介绍了Cocoa工具包的优秀特性和其中的框架,以及继承、复合、源文件组织、内存管理、对象初始化和类别创建等...

    Objective-C 2.0程序设计

    部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归 档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective- C的快速参考。  本书结构...

    Using Swift with Cocoa and Objective-C (Swift 4) EN.epub

    Using Swift with Cocoa and Objective-C (Swift 4) EN.epub 去除 DRM

    Objective-C 2.0 with Cocoa Foundation(中文)

    第 1 章,也就是本章 第 2 章,从 Hello,World!开始 第 3 章,类的声明和定义 第 4 章,继承 第 5 章,Class 类型,选择器 Selector 以及函数指针 ...第 7 章,对象的初始化以及实例变量的作用域 第 8 章,类方法以及私有方法

    《Objective-C 2.0程序设计(原书第2版)》[PDF]

    第二部分详细阐述了foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了cocoa和iphone sdk;第四部分是附录,主要列出了objective-c的快速参考。. 本书结构...

    (学习Objective-C最新最好的稀缺图书,配示例代码)Learn Objective-C On The Mac, 2009

    you learn Objective- C in this book, you’ll be ready to dive into Cocoa with a full- blown project or another book such as Learn Cocoa on the Mac or Begin- ning iPhone Development, both by Dave Mark...

    Effective Objective-C 2.0

    从语法、接口与api设计、内存管理、框架等7大方面总结和探讨了objective-c编程中52个鲜为人知和容易被忽视的特性与陷阱。书中包含大量实用范例代码,为编写易于理解、便于维护、易于扩展和高效的objective-c应用提供...

    Objective-C的语法与Cocoa框架

    7. Objective-C的description方法 8. Objective-C的异常处理 9. id类型 10. 类的继承 11. 动态判定与选择器 12. 类别Category 13. 协议@protocol 14. 内存管理 15. 常用的类型 16. 写入和读取属性 17. 对象的复制 18...

    Cocoa多线程开发Objective-C详解

    Cocoa多线程开发Objective-C详解 多线程 Objective-C iOS cocoa Xcode

Global site tag (gtag.js) - Google Analytics