当前位置:编程学习 > wap >>

object-c 内存管理(2) 内存管理策略


{

    Person *aPerson = [[Person alloc] init];

    // ...

    NSString *name = aPerson.fullName;

    // ...

    [aPerson release];

}

 

通过使用alloc方法,Person对象被创建,因此当它不再被使用时,它随后调用release方法。Person的姓名没有使用任何的获取拥有权的方法,因此它也没有调用release方法。注意:本例子使用了release而不是autorelease

 

使用autorelease发送延迟释放消息

当你需要发送延迟释放消息的时候,你可以使用autorelease,典型的使用时候是当你需要从一个方法中返回一个对象。例如,你可以像这样实现fullName方法:

- (NSString *)fullName {

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

                                          self.firstName, self.lastName] autorelease];

    return string;

}

你通过带调用alloc方法拥有了这个字符串。为了遵循内存管理规则,在你失去对string的访问权限之前,你必须释放string的所有权。如果你采用了release方法,那么string就会在它被返回之前被释放.通过使用autorelease,你表明你想去释放拥有权,但是你又允许方法的调用者在它释放之前去使用返回的字符串。

 

你也可以像下面这样实现fullName方法:

- (NSString *)fullName {

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

                                 self.firstName, self.lastName];

    return string;

}

 

遵循基本的规则,你通过调用stringWithFormat,你并没有拥有string。因此,你可以安全的从方法中返回string。

 

作为对照,下面的实现是错误的

- (NSString *)fullName {

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

                                         self.firstName, self.lastName];

    return string;

}

通过命名的约定,毫无疑问fullName的调用者拥有了返回的string,但是调用者没有任何理由去释放返回的string,于是string所占用的内存泄露了。

 

你并不拥有返回引用的对象的所有权

在cocoa中有一些方法是通过引用返回的(也就是说,它们传递了一个这样的参数ClassName ** or id *).一个通常的模式是使用NSError对象来返回错误的详细信息,如 initWithContentsOfURL:options:error: (NSData)andinitWithContentsOfFile:encoding:error: (NSString).

 

在这些情况下,上述描述的规则依然适用。当你触发它们的任何一个方法的时候,你并没有创建NSError对象,因此你并没有拥有它,你也就没有必要去释放它。例子如下:

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

NSError *error = nil;

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

                        encoding:NSUTF8StringEncoding error:&error];

if (string == nil) {

    // Deal with error...

}

// ...

[string release];

 

 

释放所有者对象的dealloc的实现                         

NSObject定义了一个dealloc方法,当一个对象没有拥有者而且它的内存被回收的时候,dealloc方法会被自动触发。Dealloc方法是为了释放对象的内存,安排它所拥有的资源,当然这也包含它拥有的实例变量。

 

下面的例子展示了在Person 类中怎么使用dealloc方法

@interface Person : NSObject {}

@property (retain) NSString *firstName;

@property (retain) NSString *lastName;

@property (assign, readonly) NSString *fullName;

@end

 

@implementation Person

@synthesize firstName=_firstName, lastName=_lastName;

// ...

- (void)dealloc

    [_firstName release];

    [_lastName release];

    [super dealloc];

}

@end

 

Attention:

·     你从不要去主动触发另一个对象的dealloc方法。

·     在自己的dealloc实现的末尾,你必须触发基类的dealloc方法

·       你不应该把系统资源的管理和对象的生命周期绑定到一起。see “Don’t Usedealloc to Manage Scarce Resources.

·     当程序终止时,对象可能并没有触发dealloc方法。由于在程序退出的时候,程序所占有的内存被自动清理,因此,仅仅让操作系统自己去清理资源比单纯的触发内存管理方法更有效。

 

Core Foundation使用相似但是不同的规则

对于Core Foundation,有相似的内存管理规则(see MemoryManagement Programming Guide for Core Foundation). 但是,Cocoa和Core Foundation的命名规范是不同的,特别的是:CoreFoundation的创建(see “The CreateRule” in MemoryManagement Programming Guide for Core Foundation)

规则并不适用于返回object-c对象的方法。例如,在下面的代码片段,你不需要释放myInstance的所有权。

MyClass *myInstance = [MyClass createInstance];

作者:lipeng08
补充:移动开发 , IOS ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,