6

我无法得到这个问题的正确答案。如果发现重复,请使用正确的参考链接使其重复。

我想知道,引用计数增加的方式是什么。我知道,alloc/init 和 retain 会增加引用计数,'copy' 是否也会将引用计数增加到 '1' ?

谢谢。

4

1 回答 1

10

copy创建一个新对象,正如方法名称所暗示的那样,接收者的副本(实际上它取决于copy每个类中方法的实现,但无论如何这是该方法的目的)。

因此,实际上它并没有真正“将引用计数增加 1”,而是创建了一个新对象,其引用计数为 1 作为任何新分配的对象,并使其具有与原始对象相同的属性/ ivar 值。

因此,假设您有一个Person具有 properties 的类namesurname并且age,如果您需要自己实现该copy方法,它看起来像这样:

-(id)copy
{
    // Create a new instance
    Person* mycopy = [[Person alloc] init];
    // Make it an exact copy of the original
    mycopy.name = self.name;
    mycopy.surname = self.surname;
    mycopy.age = self.age;
    // and return that copy
    return mycopy;
}

请注意,在这种情况下,如果您稍后修改副本,则不会修改原始副本,因为它是不同的实例。

有了这个原则,原始对象的 refcount 不会增加 1,但是您有一个 refcount 为 1 的新对象(就像您刚刚执行了 alloc/init 来自己创建这个新对象一样)并且您仍然需要释放或自动释放在某个时候你自己(如果你不使用ARC)。这就是为什么对对象的调用遵循与在某些时候调用或平衡引用计数的需要copy相同的规则retainallocreleaseautorelease


请注意,有一些例外/特殊情况,特别是对于某些被称为“不可变”的类,例如NSArrayor NSString。在这种情况下,可以合理地认为,制作作为原始副本的副本(也称为不同的对象实例),而原始无法修改,效率不高,并且可以优化。

因此,在诸如NSArrayNSString其他一些情况下,该copy方法可以简单地实现以执行简单retain操作,因为行为将与您无法修改原始(也不能修改副本)相同,因为这些本质上是不可变的类。

当然,mutableCopy(例如NSMutableArray从一个NSArray例子中获取)的实现是做一个真正的复制而不是简单的保留,copy可变子类中的方法的实现也喜欢NSMutableStringNSMutableArray一个真正的复制,但是对于请求一个不可变对象的不可变副本,分配不同实例的点通常是无用且消耗内存的,因此实现与retain.

但是所有这些可能的优化都不会改变行为(因为类是不可变的)和内存管理策略(因为您仍然需要release返回的对象copy

于 2012-10-10T09:42:07.910 回答