IOS内存管理策略(Memory Management Policy)

来源:互联网 发布:三菱plc教学软件 编辑:程序博客网 时间:2024/05/17 08:01

本文转自转自http://blog.csdn.net/chenzhiqin20/article/details/8497419?reloa.

基本model用于内存管理在一个采用引用计数的环境是由方法组合定义的协议和标准方法NSObject命名约定。这个NSObject类还定义了一个方法,dealloc,这是调用一个对象时自动销毁。

基本的model用于内存管理是在NSObject 提供reference-counted(引用计数器)的环境下。NSObjcet 还定义了dealloc 的方法,在对象自动销毁的时候调用。本文描述了所有的基本规则,您需要知道正确地管理内存在一个Cocoa程序,并提供了一些示例,正确的使用。

基本的内存管理规则

 

The memorymanagement model is based on object ownership. Any object may have one or moreowners. As long as an object has at least one owner, it continues to exist. Ifan object has no owners, the runtime system destroys it automatically. To makesure it is clear when you own an object and when you do not, Cocoa sets thefollowing policy:

 

内存管理模型是基于对象的所有权。任何对象可以有一个或更多的所有者。只要一个对象至少都有一个所有者,它继续存在。如果一个对象没有所有者,系统会自动销毁这个对象。以确保它是明确的,当你使用的一个对象和不使用一个对象的时候。设置以下策略:

l  创建一个新对象

创建一个新对象可以通过 alloc,new,copy, mutableCopy 方法。

l  保留一个对象的所有权

一个返回的对象通常是保证继续在有效在收到的方法内,该方法也可以安全地返回到其调用程序对象。

你使用保留两种情况:

1)     在访问方法的实现方法或一个init方法,把一个对象的所有权要存储作为一个属性值;

2)     以防止一个对象被废止的副作用,其他一些操作(正如在“避免引起回收的对象您正在使用”)。

l  当不再需要这个对象的时候,必须释放这个对象

你放弃所有权的一个对象通过发送一个release消息或autorelease。

l  你不能释放不是你拥有的对象。

A Simple Example

{
    Person *aPerson = [[Person alloc] init];
    // ...
    NSString *name = aPerson.fullName;
    // ...
    [aPerson release];
}

通过alloc 方法创建Person对象。所有在它不再需要使用时,通过release 方法回收。Person 的name没有被任何方法引用,所以不用发送release 消息。

使用autorelease发生一个延迟的release

你使用autorelease当你需要发送一个延迟release消息,通常当从一个方法返回一个对象。例如,您可以实现fullName方法如下:

- (NSString *)fullName {

    NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@",

                                          self.firstName, self.lastName] autorelease];

    return string;

}

你自己的字符串返回的分配。

返回通过alloc分配的String。遵守内存管理规则,你必须释放所有权的字符串在你失去了对它的引用。如果你使用release,然而,字符将在返回之前被回收 (和该方法将返回一个无效的对象)。使用生成自动释放,你意味着你要放弃所有权,但你允许调用的方法返回的字符串在回收之前。

你也可以实现fullName方法如下:

- (NSString *)fullName {

    NSString *string = [NSString stringWithFormat:@"%@ %@",

                                 self.firstName, self.lastName];

    return string;

}

下面的实现方式是错误的:

- (NSString *)fullName {

    NSString *string = [[NSString alloc] initWithFormat:@"%@ %@",

                                         self.firstName, self.lastName];

    return string;

}

调用者没有理由释放返回的字符串,它将因此被泄露。

不能拥有一个引用返回的对象

一些方法在cocoa指定返回一个对象的引用(比如,参数是ClassName* 或者id*)。一个常见模式是使用一个NSError对象包含有关错误如果一发生,就比如initWithContentsOfURL:options:error: (NSData) andinitWithContentsOfFile:encoding:error: (NSString).

在这些情况下,同样的规则适用于已经被描述。当您调用这些方法中的任何一种,不能创建NSError对象,所以你不拥有它。因此不需要release它,如在这个例子:

NSString *fileName = <#Get a file name#>;

NSError *error;

NSString *string = [[NSString alloc] initWithContentsOfFile:fileName

                        encoding:NSUTF8StringEncoding error:&error];

if (string == nil) {

    // Deal with error...

}

// ...

[string release];

 

实现dealloc放弃对象的所有者

NSObject类定义了dealloc方法。这个方法会自动调用,在没有引用的时候。这个方法的作用是免费dealloc对象的内存和处理任何资源,包括所有权的持有任何对象实例变量。

下面的例子说明了如何实现一个dealloc方法对于一个Person类:

@interface Person : NSObject

@property (retain) NSString *firstName;

@property (retain) NSString *lastName;

@property (assign, readonly) NSString *fullName;

@end

 

@implementation Person

// ...

- (void)dealloc

    [_firstName release];

    [_lastName release];

    [super dealloc];

}

@end

 

重点:不要直接调用dealloc这个方法。

你必须调用超类的实现在你最后的实现。你不应该领带管理系统资源对象的生命;请参阅“不要使用dealloc管理稀缺资源。“当一个应用程序终止,对象可能不会被发送一个dealloc消息。因为进程的内存被自动清除退出的时候,这是更有效的仅仅是为了让操作系统来清理资源比调用所有的内存管理方法

0 0