关于Objective-C手动内存管理的规则.doc_第1页
关于Objective-C手动内存管理的规则.doc_第2页
关于Objective-C手动内存管理的规则.doc_第3页
关于Objective-C手动内存管理的规则.doc_第4页
关于Objective-C手动内存管理的规则.doc_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/关于Objective-C手动内存管理的规则在ios开发中Objective-C增加了一些新的东西,包括属性和垃圾回收。那么,我们在学习Objective-C之前,最好应该先了解,从前是什么样的,为什么Objective-C要增加这些支持。这一切都跟Cocoa内存的管理规则有关系,我们知道,Objective-C中所有变量都定义为指针。指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址,如果使用不当,就会出错或者造成内存的泄露。要了解这些,就需要看看其内存管理的规则到底是什么样的。当Cocoa新手在进行内存管理时,他们看上去总是把事情变得更为复杂。遵循几个简单的规则就可以把生活变得更简单。而不遵循这些规则,他们几乎一定会造成诸如内存泄露或者将消息发送给释放掉的对象而出现的的运行错误。Cocoa不使用垃圾回收,你必须通过计算retainCount的数量进行自己的内存管理,使用-retain,-release和-autorelease。方法描述retain将一个对象的retainCount数量增加1。release将一个对象的retainCount数量减少1。autorelease在未来某些时候将retainCount数量减少1.alloc为一个对象分配内存,并设置保留值数量(retainCount)为1。copy复制一个对象,并将其做为返回值。同时设置保留值数量(retainCount)为1。保留值数量规则1、在一定的代码段中,使用-copy,-alloc和-retain的次数应该和-release,-autorelease保持一致。2、使用便利构造方法创建的对象(比如NSString的stringWithString)可以被认为会被自动释放。(autoreleased)3、在使用你自己的参数实例时,需要实现-dealloc方法来释放。例子-alloc/-release-(void)printHelloNSString*string;string=NSStringallocinitWithString:Hello;NSLog(string);/我们用alloc创建了NSString,那么需要释放它stringrelease;便利构造方法(void)printHelloNSString*string;string=NSStringstringWithFormat:Hello;NSLog(string);/我们用便利构造方法创建的NSString/我们可以认为它会被自动释放永远使用存取方法虽然有时候你可能会认为这很麻烦,但是如果你始终使用了存取方法,造成内存管理问题的麻烦将会降低很多。如果你在代码实例的参数中频繁使用-retain和-release,几乎可以肯定你做了错误的事情。例子假设我们希望设置一个Counter对象的数量值。interfaceCounter:NSObjectNSNumber*count;为了获取和设置count值,我们定义两个存取方法:-(NSNumber*)countreturncount;/无需retain或者release,/仅仅传递数值-(void)setCount:(NSNumber*)newCount/newCount值会被自动释放,那么我们希望保留这个newCount/所以需要在这里retain。newCountretain;/由于我们在这个方法中仅仅改变了计算数量的对象,我们可以在这里先释放它。因为nilrelease在objective-c中也是允许的,所以即使count值没有被指定,也可以这样调用。/我们必须在newCountretain之后再释放count,因为有可能这两个对象的指针是同一个。我们不希望不小心释放它。countrelease;/重新指定count=newCount;命名约定,注意存取方法的命名约定遵循一个模式:-参数名和-set参数名。遵循这一约定,会使你的代码可读性更强,而且,更重要地是你可以在后面使用key-value编码。(参阅NSKeyValueCoding协议)。由于我们有一个对象实例参数,我们必须实现一个释放方法:(void)deallocselfsetCount:nil;superdealloc;假设我们希望实现一个方法重置计数器,我们会有很多选择。在最开始,我们使用了一个便利构造方法,所以我们假设新的数值是自动释放的。我们不需要发送任何retain或者release消息。(void)resetNSNumber*zero=NSNumbernumberWithInt:0;selfsetCount:zero;然而,如果我们使用-alloc方法建立的NSNumber实例,那我们必须同时使用一个-release。(void)resetNSNumber*zero=NSNumberallocinitWithInt:0;selfsetCount:zero;zerorelease;常见错误在简单的情况下,以下代码几乎一定可以正常运行,但是由于可能没有使用存取方法,下面的代码在某些情况下几乎一定会出问题。错误-没有使用存取方法(void)resetNSNumber*zero=NSNumberallocinitWithInt:0;countreleasecount=zero;错误-实例泄露(void)resetNSNumber*zero=NSNumberallocinitWithInt:0;selfsetCount:zero;新建的NSNumber数值数量是1(通过alloc),而我们在这个方法里没有发出-release消息。那么这个NSNumber就永远不会被释放了,这样就会造成内存泄露。错误-对已经释放的实例发送-release消息-(void)resetNSNumber*zero=NSNumbernumberWithInt:0;selfsetCount:zero;zerorelease;你随后在存取count的时候在这里就会出错。这个简便构造方法会返回一个自动释放的对象,你无需发送其他释放消息。这样写代码意味着,由于对象已经被自动释放,那么当你释放时,retaincount将被减至0,对象已经不存在了。当你下次希望获取count值时,你的消息会发到一个不存在的对象(通常这样你会得到一个SIGBUS10的错误提示)。经常造成混淆的情况数组和其他集合类当对象被加入到数组、字典或者集合中,集合类会将其保留。当集合被释放的同时,对象也会收到一个释放消息。如果你希望写一个建立数字数组的例子,你可能会这么写:NSMutableArray*array;inti;/for(i=0;i10;i+)NSNumber*n=NSNumbernumberWithInt:i;arrayaddObject:n;在这个例子里,你无需保留新建的数值,因为数组会帮你保留。NSMutableArray*array;inti;/for(i=0;i10;i+)NSNumber*n=NSNumberallocinitWithInt:i;arrayaddObject:n;nrelease;本例中,在for循环里你需要给n发送一个-release消息,因为你需要始终在-alloc之后将n的数量保持为1。这么做的原因是当其通过-addObject:方法被添加至数组中时,数组已经将其保存起来。即使你释放了n,但是这个数字由于已经保存在数组里,所

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论