【问题标题】:What exactly is happening when I set an object's property using an accessor method?当我使用访问器方法设置对象的属性时到底发生了什么?
【发布时间】:2011-10-26 05:44:27
【问题描述】:

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

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

实际发生了什么?是否设置了对分配给myString 的空间的引用?还是因为我在foo 上调用了retain,所以它是否获取了为myString 分配的内存并将其设置为为foo 分配的内存?

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

【问题讨论】:

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


    【解决方案1】:

    这完全取决于如何声明属性。因为你的是(retain),所以它会保持相同的对象指针,并且会自动发送-retain,这样无论调用者是否持有引用,它都能确保访问内存。如果您使用(copy),它将发送-copy,这将创建一个新对象,该对象是旧对象的副本(前提是该对象符合`NSCopying)。

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

    【讨论】:

    • 那么这是否意味着如果我更改 myString 或 foo,它会更改另一个,因为它们实际上只是对同一个变量的引用。
    • 有点——记住你不能更改NSString,只能更改NSMutableString。而且NSString 属性通常是(copy)
    • 是的。这不是一个真实的例子,我只是在谈论一般的对象,而不是字符串。所以说它是一个nsmutablestring,我确实改变了一个,它会改变另一个吗?
    • 是的,如果不是(copy)。试试看!
    【解决方案2】:

    @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; 时,您并不是在复制对象本身,而是在创建另一个指向该对象的指针。综合属性也不例外。

    【讨论】:

    • 这仅适用于(nonatomic) 属性,我相信:)
    • 是的。如果问题中的属性是原子的,情况会略有不同。
    • 我相信汤姆在回答的开头确实包含了一个警告。对于 OP 使用的关键字,合成方法的实现是正确的。
    • 实际上,@synthesize foo; 创建的代码类似于:return [[foo retain] autorelease];。如果属性是原子的,它也会在setFoo: 中的代码周围加锁。
    • FWIW,字符串属性通常声明为(copy),然后复制
    【解决方案3】:

    当您执行[myClass setFoo:myString]; 时,myString 指向的对象的保留计数会增加一

    最初,当您分配一个字符串并将引用存储在myString 中时,保留计数为 1。将其存储在像您一样具有保留的属性中时,其保留计数增加到 2。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-27
      • 2011-01-21
      • 2012-12-14
      • 2014-08-22
      • 2019-07-13
      • 2019-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多