详解Objective-C2.0 关于Objective-C内存管理规则是本文要介绍的内容,不多说,先来看内容。Objective-C2.0增加了一些新的东西,包括属性和垃圾回收。那么,我们在学习Objective-C2.0之前,最好应该先了解,从前是什么样的,为什么Objective-C2.0要增加这些支持。
这一切都跟Cocoa内存的管理规则有关系,我们知道,Objective-C中所有变量都定义为指针。指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址,如果使用不当,就会出错或者造成内存的泄露。要了解这些,就需要看看其内存管理的规则到底是什么样的。
这篇文章也应该做为苹果开发工具中提供的性能调试工具Instruments使用前必读知识进行阅读。要知道,如果你使用Objective-C 2.0,那么本文描述的大部分工作你都不需要自己去处理了。但是这并不意味着你可以不了解它,相反,只有你对内存管理规则更加了解,你才能更好地使用Objective-C 2.0带来的便利。
当Cocoa新手在进行内存管理时,他们看上去总是把事情变得更为复杂。遵循几个简单的规则就可以把生活变得更简单。而不遵循这些规则,他们几乎一定会造成诸如内存泄露或者将消息发送给释放掉的对象而出现的的运行错误。
Cocoa不使用垃圾回收(当然,Objective-C 2.0之后开始就使用了),你必须通过计算reference的数量进行自己的内存管理,使用-retain, -release和-autorelease。
方法描述
retain
将一个对象的reference数量增加1。
release
将一个对象的reference数量减少1。
autorelease
在未来某些时候将reference数量减少1.
alloc
为一个对象分配内存,并设置保留值数量(retain count)为1。
copy
复制一个对象,并将其做为返回值。同时设置保留值数量(retain count)为1。
保留值数量规则
1、在一定的代码段中,使用-copy,-alloc和-retain的次数应该和-release,-autorelease保持一致。
2、使用便利构造方法创建的对象(比如NSString的stringWithString)可以被认为会被自动释放。(autoreleased)
3、在使用你自己的参数实例时,需要实现-dealloc方法来释放。
例子
- -alloc/-release
- -(void)printHello
- {
- NSString*string;
-
string=[[NSStringalloc]initWithString:@"Hello"];
- NSLog(string);
- //我们用alloc创建了NSString,那么需要释放它
- [stringrelease];
- }
便利构造方法
- (void)printHello
- NSString*string;
-
string=[NSStringstringWithFormat:@"Hello"];
- NSLog(string);
- //我们用便利构造方法创建的NSString
- //我们可以认为它会被自动释放
永远使用存取方法
虽然有时候你可能会认为这很麻烦,但是如果你始终使用了存取方法,造成内存管理问题的麻烦将会降低很多。
如果你在代码实例的参数中频繁使用-retain和-release,几乎可以肯定你做了错误的事情。
例子
假设我们希望设置一个Counter对象的数量值。
- @interfaceCounter:NSObject
- {
- NSNumber*count;
- }
为了获取和设置count值,我们定义两个存取方法:
- -(NSNumber*)count
- {
- returncount;
- //无需retain或者release,
- //仅仅传递数值
- }
- -(void)setCount:(NSNumber*)newCount
- {
- //newCount值会被自动释放,那么我们希望保留这个newCount
- //所以需要在这里retain。
- [newCountretain];
- //由于我们在这个方法中仅仅改变了计算数量的对象,我们可以在这里先释放它。因为[nilrelease]在objective-c中也是允许的,所以即使count值没有被指定,也可以这样调用。
- //我们必须在[newCountretain]之后再释放count,因为有可能这两个对象的指针是同一个。我们不希望不小心释放它。
- [countrelease];
- //重新指定
-
count=newCount;
- }
命名约定,注意存取方法的命名约定遵循一个模式: -参数名 和 -set参数名。
遵循这一约定,会使你的代码可读性更强,而且,更重要地是你可以在后面使用key-value编码。(参阅NSKeyValueCoding协议)。
由于我们有一个对象实例参数,我们必须实现一个释放方法:
- (void)dealloc
- {
- [selfsetCount:nil];
- [superdealloc];
- }
假设我们希望实现一个方法重置计数器,我们会有很多选择。在最开始,我们使用了一个 便利构造方法,所以我们假设新的数值是自动释放的。我们不需要发送任何retain或者release消息。
- (void)reset
- {
-
NSNumber*zero=[NSNumbernumberWithInt:0];
- [selfsetCount:zero];
- }
然而,如果我们使用-alloc方法建立的NSNumber实例,那我们必须同时使用一个-release。
- (void)reset
-
NSNumber*zero=[[NSNumberalloc]initWithInt:0];
- [selfsetCount:zero];
- [zerorelease];
常见错误
在简单的情况下,以下代码几乎一定可以正常运行,但是由于可能没有使用存取方法,下面的代码在某些情况下几乎一定会出问题。
错误-没有使用存取方法
- (void)reset
- {
-
NSNumber*zero=[[NSNumberalloc]initWithInt:0];
- [countrelease]
-
count=zero;
- }
错误-实例泄露
- (void)reset
- {
-
NSNumber*zero=[[NSNumberalloc]initWithInt:0];
- [selfsetCount:zero];
- }
新建的NSNumber数值数量是1(通过alloc),而我们在这个方法里没有发出-release消息。那么这个NSNumber就永远不会被释放了,这样就会造成内存泄露。
错误-对已经释放的实例发送-release消息
- -(void)reset
- {
-
NSNumber*zero=[NSNumbernumberWithInt:0];
- [selfsetCount:zero];
- [zerorelease];
- }
你随后在存取count的时候在这里就会出错。这个简便构造方法会返回一个自动释放的对象,你无需发送其他释放消息。
这样写代码意味着,由于对象已经被自动释放,那么当你释放时,retain count将被减至0,对象已经不存在了。当你下次希望获取count值时,你的消息会发到一个不存在的对象(通常这样你会得到一个SIGBUS 10的错误提示)。
经常造成混淆的情况
数组和其他集合类
当对象被加入到数组、字典或者集合中,集合类会将其保留。当集合被释放的同时,对象也会收到一个释放消息。如果你希望写一个建立数字数组的例子,你可能会这么写:
- NSMutableArray*array;
- inti;
- //…
-
for(i=0;i<10;i++)
- {
-
NSNumber*n=[NSNumbernumberWithInt:i];
- [arrayaddObject:n];
- }
在这个例子里,你无需保留新建的数值,因为数组会帮你保留。
- NSMutableArray*array;
- inti;
- //…
-
for(i=0;i<10;i++)
- {
-
NSNumber*n=[[NSNumberalloc]initWithInt:i];
- [arrayaddObject:n];
- [nrelease];
- }
本例中,在for循环里你需要给n发送一个-release消息,因为你需要始终在-alloc之后将n的数量保持为1。这么做的原因是当其通过-addObject:方法被添加至数组中时,数组已经将其保存起来。即使你释放了n,但是这个数字由于已经保存在数组里,所以不会被释放。
为了了解这些,假设你自己就是编写数组类的人。你不希望接收的对象未经你同意就消失,所以你会在对象传递进来时,对其发送一个-retain消息。如果他们被删除,你同时也要对应地发送一个-release消息。在你自己-dealloc时,你也要给你收到的所有对象发送一个-release。
小结:详解Objective-C2.0 关于Objective-C内存管理规则的内容介绍完了,希望本文对你有所帮助。
本文来自http://mobile.51cto.com/iphone-276599.htm
分享到:
相关推荐
objective-c 内存管理 alloc init release
Objective-C内存管理 刚接触的的人可能有些迷惑,看了本文 你将成为Objective-C内存管理高手 文字 高清版
详细介绍 objective-c内存管理和原理剖析
初学objectice-C的朋友都有一个困惑,总觉得对objective-C的内存管理机制琢磨不透,程序经常内存泄漏 或莫名其妙的崩溃。我在这里总结了自己对objective-C内存管理机制的研究成果和经验,写了这么一个由 浅入深的...
Objective-C内存管理教程和原理剖析,很详细全面的内存管理教程
Objective-C内存管理课件.docx ,assign,retain,copy
Objective-C 内存管理 深入浅出发,熟悉内存管理。
Objective-C高级编程 iOS与OS X多线程和内存管理.pdf
第7章到第10章讲述objective-c的基础框架,以及文件操作、内存管理、数据保存等内容。第11章讲述了应用工具框架。第12、13章分别讲述了如何开发iphone/ipad应用程序。第14章讲述了objective-c++和访问mysql数据库的...
《Objective-C 程序设计(第4版)》已经为iOS 5和Xcode4.2中的重大变更做了全面更新,最大的改动是引入了自动引用计数(ARC),并详细说明了如何在Objective-C编程过程中使用ARC提升和简化内存管理。
Objective-C高级编程 iOS与OS X多线程和内存管理.
Objective-C的内存管理机制与.Net/Java那种全自动的垃圾回收机制是不同的,它本质上还是C语言中的手动管理方式,只不过稍微加了一些自动方法。 1 Objective-C的对象生成于堆之上,生成之后,需要一个指针来指向它。 ...
本书全面而系统地讲述Objective-C语言的基础知识和面向对象编程的重要概念,结合实例介绍了Cocoa工具包的优秀特性和其中的框架,以及继承、复合、源文件组织、内存管理、对象初始化和类别创建等众多重要的面向对象...
第二部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective-C的快速参考。 ...
部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归 档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective- C的快速参考。 本书结构...
第二部分详细阐述了foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了cocoa和iphone sdk;第四部分是附录,主要列出了objective-c的快速参考。. 本书结构...
帮助学习关于OC中内存管理的知识点
Objective-C 2.0之前需要了解的:关于Obj-C内存管理的规则。
5、值类型会被放入栈qf他们依次紧密排列f在内存q占有一块连续的内存空间f遵循先进后出的原则 6、引用类型会被放到堆qf当给对象分配内存空间时f会随机的从内存当