iOS内存管理策略和实践

内存管理策略(memory Management Policy)
NSObject protocol中定义的的方法和标准命名惯例一起提供了一个引用计数环境,内存管理的基本模式处于这个环境中。 NSObject类定义了一个方法叫dealloc,当对象销毁的时候,dealloc会被自动调用 。本文描述,在Cocoa中所有正确管理内存基本规则,并提供了一些使用正确的例子。

【基本的内存管理规则】
内存管理模式基于对象的“所有权”上。任何对象都会被有一个或多个使用者引用,只要对象还有一个使用者,该对象就应该继续存在。如果一个对象没有使用者了,系统将自动销毁它。为了让开发者清晰的了解:使用对象和不再使用对象的场景,Cocoa设置了以下策略:
1.管好自己创建的对象。开发者使用alloc、new、copy和mutableCopy来创建对象。
 
2.使用retain来获得对象的所有权。某个函数接受的对象,通常保证在该函数调用期间仍然可用,并可以安全返回对象给上层调用者。开发者在以下两种情况下使用retain
1)在“访问函数”(accessor)的实现中或者在init方法,为了将对象作为自己的属性。
2)防止对象被其他操作释放掉,从而变为无效的对象。

3.当你不在需要的时候,必须放弃对象所有权。

一个简单的例子
看看下面的代码段,可以证明刚刚的所说的策略
  
  
  1. {   
  2.     Person *aPerson = [[Person alloc] init];   
  3.     // ...   
  4.     NSString *name = aPerson.fullName;   
  5.     // ...   
  6.     [aPerson release];   
  7. }   
Person被通过alloc创建之后,当Person不在使用的时候,发送了一个release的消息。name这个变量没有使用,所以name不必发送release消息。
 
使用autorelease来发送一个延迟的release,能保证调用者在string销毁前使用返回值。
典型的使用场景:函数返回一个对象的时候。例如,你可以像这样实现fullName的方法:
  
  
  1. - (NSString *)fullName 
  2. {   
  3.     NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@",   
  4.                                           self.firstName, self.lastName] autorelease];   
  5.     return string;   
  6. }   
上面就是典型的场景:你想放弃对象的所有权,但是又想让调用者在string销毁前使用返回值。
 
还可以通过下面的实现达到上面的效果:
  
  
  1. - (NSString *)fullName {   
  2.     NSString *string = [NSString stringWithFormat:@"%@ %@",   
  3.                                  self.firstName, self.lastName];   
  4.     return string;   
  5. }   
根据命名惯例,full name方法不具备返回值的所有权。因此,调用者无需对返回值string进行release

开发者不应该获得“通过引用传递的对象”的所有权
Cocoa中的一些方法,指定是传递引用。例如NSError对象包涵错误的信息,比如:initWithContentsOfURL:options:error: (NSData) and initWithContentsOfFile:encoding:error: (NSString).这种情况,之前的规则中已经描述过了。你调用这些方法,但是没有创建NSError对象,所以,你没有它的所有权。因此不用release,比如:
  
  
  1. NSString *fileName = <#Get a file name#>;   
  2. NSError *error;   
  3. NSString *string = [[NSString alloc] initWithContentsOfFile:fileName   
  4.                         encoding:NSUTF8StringEncoding error:&error];   
  5. if (string == nil) {   
  6.     // Deal with error...   
  7. }   
  8. // ...   
  9. [string release];   

【实现dealloc放弃对象的所有权】
NSObject类定义了一个方法dealloc,当某个对象没有使用者,并它的内存是可再生的,delloc就自动被调用。delloc的角色就是释放对象占用的内存并且处理自己所拥有的资源,包括本身变量的释放。
下面的代码展示了,如何实现Person类的dealloc函数。
  
  
  1. @interface Person : NSObject   
  2. @property (retain) NSString *firstName;   
  3. @property (retain) NSString *lastName;   
  4. @property (assign, readonly) NSString *fullName;   
  5. @end   
  6.     
  7. @implementation Person   
  8. // ...   
  9. - (void)dealloc   
  10.     [_firstName release];   
  11.     [_lastName release];   
  12.     [super dealloc];   
  13. }   
  14. @end   
也可以这么理解,如果一个对象中有copy和retain,那么需要再dealloc中释放

重要】
任何时候,不要直接调用某一对象的dealloc。
不许在dealloc的最后一行调用父类的dealloc
不要尝试管理系统资源。(参考内存管理实践)
应用程序终止的时候,对象的dealloc可能不会被调用。因为进程的内存是自动清除退出,让操作系统清理资源比调用所有的内存管理方法更有效地。
 
Core Foundation使用相似的却又不同的规则
Core Foundation对象使用类似的内存管理规则(查看Memory Management Programming Guide for Core Foundation),但是Cocoa和Core Foundation的命名管理并不相同。尤其是,Core Foundation的Create Rule(在Memory Management Programming Guide for Core Foundation中查看“The Create Rule” )并不适用于返回Objective-C对象的方法。比如以下代码片段:
  
  
  1. MyClass *myInstance = [MyClass createInstance]; 


Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值