Objective c 什么增加了一个对象';我们算什么?
这是我指的代码Objective c 什么增加了一个对象';我们算什么?,objective-c,memory,memory-management,retain,Objective C,Memory,Memory Management,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 /
// 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
//Person.h
@接口人:NSObject{
NSString*名字;
NSString*lastName;
}
@结束
//人
@执行人
-(id)init{
如果(![super init])返回nil;
名字=@“约翰”;
lastName=@“Doe”;
}
@结束
//我的班级
@MyClass的实现
.....
-(NSArray*)找人{
NSMUTABLEARRY*array=[[NSMUTABLEARRY alloc]init];
int i;
对于(i=0;i<10;i++){
Person*p=[[Person alloc]init];
[array addObject:p];
}
返回数组;
}
.....
@结束
现在,我知道在这个示例代码中没有内存管理。需要什么
在getPeople循环中,我分配一个人(重新计入1),然后将其添加到数组中。保留计数现在是2,对吗?如果是2,我应该在将其添加到数组中后进行[p release]'运算,将重新计数降低到1吗
调用方有责任释放方法返回的数组,这对吗?(这也将释放此人的内存及其实例变量,假设其计数为1)
我读过苹果的内存管理文档,但我想我最不清楚的是,是什么增加了对象的保留计数?不过,我想我理解了释放的责任是谁。根据苹果公司的说法,这是最基本的规则:
如果您使用名称以“alloc”或“new”开头或包含“copy”的方法(例如,alloc、newObject或mutableCopy)创建对象,或者向其发送retain消息,则您将获得对象的所有权。您负责放弃使用“释放”或“自动释放”拥有的对象的所有权。在任何其他时间收到对象时,都不能释放它
bobDevil的一句话“只关心您显式添加到项目中的保留计数”让我觉得很有意思。在阅读了苹果的所有权政策之后,本质上,创建新对象的对象/方法是负责发布/它的/对它感兴趣的对象/方法。这是正确的吗
现在,让我们假设我有一个方法,它接收一个对象,并将其分配给一个实例变量。我需要正确地保留接收到的对象,因为我仍然对它感兴趣
如果有任何错误,请告诉我。当您专门调用alloc时,Retain计数会增加,因此您需要明确地释放它 factory方法通常会给您一个自动释放的对象(例如[NSMutableArray]——您必须特别保留它以使其在任意时间内保持不变) 至于NSArray和NSMutableArray addObject:,则需要其他人进行评论。我相信,就类如何将自己的内存管理作为一种设计模式来处理而言,您将类视为黑匣子,因此您永远不会显式地释放传递到NSArray中的内容。当它被销毁时,它应该处理递减保留计数本身 如果您将IVAR声明为@property(retain)suchanduchivar之类的属性,并在实现中使用@synthesis,您还可以得到一个隐式的retain。Synthesis基本上为您创建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++
编辑:
至于内存管理,只要将对象添加到数组中,就完成了它。。。因此:
for (i = 0; i < 10; i++) {
Person *p = [[Person alloc] init];
[array addObject:p];
[p release];
}
(i=0;i<10;i++)的{
Person*p=[[Person alloc]init];
[array addObject:p];
[p释放];
}
Josh你一般/不/应该担心保留计数。这是内部实现的。您应该只关心是否要通过保留对象来“拥有”对象。在上面的代码中,数组应该拥有对象,而不是您(在循环之外,除了通过数组之外,您甚至没有对它的引用)。因为您拥有
[[Person alloc]init]
,所以您必须释放它
因此
此外,“getPeople”的调用方不应拥有该数组。这是惯例。你应该先自动释放它
NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];
您需要阅读苹果关于内存管理的文档:将其添加到阵列后,保留计数为2是正确的。但是,您应该只关心显式添加到项目中的保留计数 保留一个对象是一个合同,上面写着“我还没跟你说完,不要走开。”一个基本的经验法则(也有例外,但通常都有文档记录)是,当你分配一个对象或创建一个副本时,你拥有这个对象。这意味着您获得的对象的保留计数为1(未自动删除)。在这两种情况下,您应该在完成后释放它。此外,如果明确保留对象,则必须释放它 因此,具体到你的例子,当你创建这个人时,你有一个保留计数。您将其添加到一个数组中(该数组对其执行任何操作,您不在乎),然后您就完成了对此人的操作,因此您可以释放它:
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
另外,正如我上面所说的,您通常只在alloc或copy期间拥有该对象,因此为了与另一方面的一致,您应该返回autoreleased数组,以便getPeople方法的调用方不拥有它
return [array autorelease];
编辑:
正确,如果您创建了它,则必须释放它。如果你对它感兴趣(通过retain),你必须释放它。Josh说NSMutableArray默认标记为自动释放?你必须显式地自动释放你创建的对象。
return [array autorelease];