Tho*_*s R 13 memory memory-management objective-c retain
这是我指的代码.
// Person.h
@interface Person : NSObject {
NSString *firstName;
NSString *lastName;
}
@end
// Person.m
@implementation Person
- (id)init {
if (![super init]) return nil;
firstName = @"John";
lastName = @"Doe";
}
@end
// MyClass.m
@implementation MyClass
.....
- (NSArray *)getPeople {
NSMutableArray *array = [[NSMutableArray alloc] init];
int i;
for (i = 0; i < 10; i++) {
Person *p = [[Person alloc] init];
[array addObject:p];
}
return array;
}
.....
@end
Run Code Online (Sandbox Code Playgroud)
现在,我知道此示例代码中没有内存管理.需要什么?
在getPeople循环中,我分配了一个Person(retainCount 1),然后将它添加到数组中.保留计数现在是2,对吗?如果它是两个,我应该在将它添加到数组后[p release],将retainCount恢复为1吗?
我是对的,调用者有责任释放该方法返回的数组吗?(这也可以释放Person的内存和它们的实例变量,假设它们的计数为1).
我已经阅读了Apple的内存管理文档,但我想我最不清楚的是,增加对象保留的数量是多少?不过,我想我已经掌握了释放谁的责任的想法.据Apple称,这是基本规则:
如果使用名称以"alloc"或"new"开头或包含"copy"(例如,alloc,newObject或mutableCopy)的方法创建对象,或者向其发送保留消息,则获取对象的所有权.您有责任使用release或autorelease放弃您拥有的对象的所有权.在收到对象的任何其他时间,您不得释放它.
bobDevil的句子"只担心你明确添加到项目的保留计数"让它点击给我.在阅读Apple的所有权政策之后,基本上,创建新对象的对象/方法是负责释放/它/兴趣的对象/方法.它是否正确?
现在,假设我是一个接收对象的方法,并将其分配给实例变量.我需要保持收到的对象正确,因为我仍然对它有兴趣吗?
如果这些不正确,请告诉我.
bob*_*vil 18
将数据添加到数组后,保留计数为2是正确的.但是,您应该只担心显式添加到项目中的保留计数.
保留一个物体是一份合同,上面写着"我没有和你一起做过,不要离开." 一个基本的经验法则(有例外,但通常记录它们)是你在分配对象或创建副本时拥有对象.这意味着您将获得保留计数为1(未自动释放)的对象.在这两种情况下,您应该在完成后释放它.此外,如果您明确保留了对象,则必须将其释放.
因此,为了特定于您的示例,在创建Person时,您有一个保留计数.你把它添加到一个数组(使用它做什么,你不关心),然后你完成了Person,所以你释放它:
Person *p = [[Person alloc] init]; //retain 1, for you
[array addObject:p]; //array deals with p however it wants
[p release]; //you're done, so release it
Run Code Online (Sandbox Code Playgroud)
另外,正如我上面所说,你通常只在alloc或copy期间拥有对象,所以为了与事物的另一面保持一致,你应该返回自动释放的数组,以便getPeople方法的调用者不拥有它.
return [array autorelease];
Run Code Online (Sandbox Code Playgroud)
编辑:正确,如果您创建它,您必须释放它.如果您对它产生兴趣(通过保留),您必须将其释放.
当您专门调用 alloc 时,保留计数会增加,因此您需要明确地释放它。
工厂方法通常会为您提供一个自动释放的对象(例如 [NSMutableArray 数组] - 您必须专门保留它以将其保留任何时间长度。)。
至于 NSArray 和 NSMutableArray addObject:,其他人将不得不发表评论。我相信您将类视为黑匣子,因为它们将自己的内存管理作为一种设计模式处理,因此您永远不会明确释放已传递给 NSArray 的内容。当它被销毁时,它应该处理减少保留计数本身。
如果您将 ivars 声明为诸如 @property (retain) suchAndSuchIvar 之类的属性,并在您的实现中使用 @synthesize,您还可以获得某种隐式保留。Synthesize 基本上为您创建了 setter 和 getter,如果您专门调用 (retain),setter 将保留传入它的对象。它并不总是很明显,因为 setter 可以这样构造:
Person fart = [[Person alloc] init];
fart.firstName = @"Josh"; // this is actually a setter, not accessing the ivar
// equivalent to [fart setFirstName: @"Josh"], such that
// retainCount++
Run Code Online (Sandbox Code Playgroud)
编辑:
至于内存管理,只要将对象添加到数组中,就完成了……所以:
for (i = 0; i < 10; i++) {
Person *p = [[Person alloc] init];
[array addObject:p];
[p release];
}
Run Code Online (Sandbox Code Playgroud)
乔希
归档时间: |
|
查看次数: |
14401 次 |
最近记录: |