当我使用访问器方法设置对象的属性时到底发生了什么?

时间:2011-08-13 00:36:59

标签: iphone objective-c memory-management properties accessor

假设我有一个名为MyClass的对象,它有一个定义为@property (nonatomic, retain) NSString *foo;的属性,我合成了该属性。

然后在另一个类中,说应用程序委托我定义一个字符串(但它可以是任何东西)NSString *myString = [[NSString alloc] initWithString:@"Hi"];并调用MyClass的实例:[myClass setFoo:myString];

实际发生了什么?是否设置了为myString分配的空间的引用?或者它是否获得myString的已分配内存中的内容并将其设置为foo的已分配内存,因为我在retain上调用了foo

我必须在应用程序委托中释放myString。我必须在MyClass中释放foo,因为它被保留了,但是我必须再次释放它,因为已经为它分配了另一个alloc'd变量吗?

3 个答案:

答案 0 :(得分:2)

这一切都取决于财产的声明方式。因为你的是(retain),它将保持相同的对象指针,并自动发送-retain,这样无论调用者是否持有引用,它都可以确保访问内存。如果您使用(copy),它将发送-copy,这将生成一个旧对象的旧对象(假设该对象符合`NSCopying)。

这一切都发生在附件实现中,这通常是在您使用@synthesize时为您生成的。如果您实现自己的,请务必使用正确的行为!

答案 1 :(得分:1)

@synthesize基本上为您创建了两种方法。在您的情况下,这两种方法类似于:

-(NSString*) foo;
{
    return foo; //synthesized ivar
}

-(void) setFoo:(NSString*)newValue;
{
    if(foo != newValue){
        [foo release];
        foo = [newValue retain];
    }
}

但是,@synthesize不会释放dealloc中的值,因此您必须手动执行此操作。

Objective-C中的对象被视为指针,所以当你说NSString* a = b;你没有复制对象本身时,你只是在做另一个指向对象的指针。合成属性也不例外。

答案 2 :(得分:0)

当你myString

时,对象[myClass setFoo:myString];指向它的保留计数增加1会发生什么?

最初,当您分配字符串并将引用存储在myString中时,保留计数为1.将其存储在保留的属性中,使其保留计数增加到2.

不,你不必再发布它。最大保留计数为2.因此有2个版本。