iOS:复制属性

iOS:复制属性,ios,Ios,我找不到这个问题的正确答案。如果发现重复,请使用正确的参考链接使其重复 我想知道,引用计数递增的方式是什么。我知道,alloc/init和retain会增加引用计数,“copy”是否也会将引用计数增加到“1” 谢谢。copy创建了一个新对象,正如方法名称所示,它是接收者的副本(事实上,它取决于每个类中copy方法的实现,但无论如何,这是该方法的目标) 因此,实际上它并没有真正“将的引用计数增加1”,而是创建了一个新对象,refcount为1作为任何新分配的对象,并使其具有与原始对象相同的属性/i

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

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


谢谢。

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

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

因此,假设您有一个
Person
类,其属性为
name
姓氏
年龄
,如果您需要自己实现
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
遵循与
retain
alloc
相同的规则,即需要调用
release
autorelease
来平衡某个点的引用计数


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

因此,在诸如
NSArray
NSString
等情况下,
copy
方法可以简单地实现,以执行一个简单的
retain
,因为行为与您不能修改原始类(以及副本)相同,因为它们本质上是不可变的类

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


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

好的,到目前为止我对“复制”的理解基本上是复制它的原样并复制另一个对象。但是,新复制的对象不会创建新地址,而是(实际地址和重复地址)都指向内存中的同一位置。因此,当使用“copy”时,并没有将引用计数增加到“1”。请参阅我的编辑,了解在诸如
NSString
/
NSArray
/
NSDictionary
/等不可变类的情况下通常进行的优化。在不可变对象的不可变副本的情况下,
copy
方法只执行
retain
,因为在这种情况下,它的行为是相同的(因为您既不能修改原件也不能修改副本,不需要有单独的实例)。因此,在这种特殊的优化情况下,调用
copy
将是调用
retain
的同义词。但是您不必担心这个optim&implementation细节,因为这不会改变要应用的行为或内存管理规则。好的,最后我从您非常详细的解释中理解了(非常感谢!)“copy”将引用计数增加到“1”。所以,有三种方法,例如alloc/init、retain和copy引用计数可以增加“1”。是的。实际上,对于
copy
的情况,最好说原始对象的refcount加上copy返回的对象的refcount之和比
copy
之前的原始对象的refcount多1。
copy
返回的对象与原始对象相同,但其refcount增加了一(因为在不可变对象情况下进行了优化),或者
copy
方法返回一个新的独立实例(对于可变情况),refcount为1,而原始对象的refcount没有修改。最后,总的refcount和是多了一个,是的。但是请注意,所有这些(它是返回一个真实副本,还是在增加refcount后通过返回自身来优化它)实际上都是实现细节。在实践中,您不应该为这些优化细节而烦恼,而应该记住概念的封装。因此,您应该知道的唯一一点是,
copy
的目的是返回对象的一个副本,并且您需要
释放该副本(无论它是实际副本还是实际副本都无关紧要),就像您平衡
保留
分配
一样。剩下的只是每个类的内部实现细节。