zoukankan      html  css  js  c++  java
  • iOS 内存管理策略

    内存管理策略(memory Management Policy)

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

    【基本的内存管理规则】

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

    一个简单的例子

    看看下面的代码段,可以证明刚刚的所说的策略

    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

    典型的使用场景:函数返回一个对象的时候。例如,你可以像这样实现fullName的方法:

    1. - (NSString *)fullName {  
    2.     NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@",  
    3.                                           self.firstNameself.lastName] autorelease];  
    4.     return string;  
    5. }  

    上面就是典型的场景:你想放弃对象的所有权,但是又想让调用者在string销毁前使用返回值。


    还可以通过下面的实现达到上面的效果:

    1. - (NSString *)fullName {  
    2.     NSString *string = [NSString stringWithFormat:@"%@ %@",  
    3.                                  self.firstNameself.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 (retainNSString *firstName;  
    3. @property (retainNSString *lastName;  
    4. @property (assign, readonlyNSString *fullName;  
    5. @end  
    6.    
    7. @implementation Person  
    8. // ...  
    9. - (void)dealloc  
    10.     [_firstName release];  
    11.     [_lastName release];  
    12.     [super dealloc];  
    13. }  
    14. @end  


    【重要】
    任何时候,不要直接调用某一对象的dealloc。
    不许在dealloc的最后一行调用父类的dealloc
    不要尝试管理系统资源。(参考内存管理实践)
    应用程序终止的时候,对象的dealloc可能不会被调用。因为进程的内存是自动清除退出,让操作系统清理资源比调用所有的内存管理方法更有效地。


    Core Foundation使用相似的却又不同的规则

    点击查看原文地址

  • 相关阅读:
    kvm虚拟化介绍(1)
    linux进阶之yum管理
    python基础之面向对象(三))(实战:烤地瓜(SweetPotato))
    python基础之python牛逼的设计模式
    zabbix监控之邮件报警通知
    zabbix监控之概念和安装
    nosql数据库之Redis集群
    nosql数据库之Redis持久化、备份和主从配置
    nosql数据库之Redis概念及基本操作
    python基础之面向对象(二)(封装、继承、多态)
  • 原文地址:https://www.cnblogs.com/lisa090818/p/3707549.html
Copyright © 2011-2022 走看看