Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 什么增加了一个对象';我们算什么?_Objective C_Memory_Memory Management_Retain - Fatal编程技术网

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];