复制还会转移保留计数吗?

Ahm*_*med 1 memory-management objective-c

假设我有一个对象,例如NSString,保留计数为5.当我在其上调用copy时,我得到一个对象的新副本; 这个新对象是否具有其原始对象的保留计数?

Mar*_*n R 5

这取决于.copy是一种方便的方法copyWithZone:,并且"NSCopying Protocol Reference"声明:

您实施此协议的选项如下:

  • 落实NSCopying使用alloc,并init...在课堂上不继承copyWithZone :.
  • NSCopying通过在继承行为copyWithZone:时调用超类来实现NSCopying.如果超类实现可能使用该NSCopyObject函数,则对保留对象的指针实例变量进行显式赋值.
  • 实现NSCopying通过保留原有的,而不是创建一个新的副本,上课的时候,其内容是不变的.

(在所有反馈之后,我修改了以下两个陈述.)

例如,NSString是一个不可变对象,copy只保留对象并返回指向同一对象的指针.保留对象可能会增加保留计数,但不一定(如字符串文字的情况).

复制一个NSMutableString可能会创建一个新对象并返回该对象.新对象将具有独立于原始对象的自己的保留计数.

但你不应该关心这种差异.使用手动引用计数, copy返回您拥有的对象并最终必须释放.使用ARC,编译器可以自动处理.

  • @Benoit:这是不正确的,我在发布答案之前用测试程序检查了它. - 我的观点是,*immutable*对象可以自由地增加一个副本的保留计数,这种情况发生在`NSString`中.我现在说你应该期待它. (2认同)
  • 没有必要猜测它是如何工作的.你可以自己看看它是如何实现的.http://www.opensource.apple.com/source/CF/CF-744.19/CFString.c查看`CFStringCreateCopy()`.它检查字符串是否可变.如果不是,并且某些其他角落情况不起作用,则它只调用`CFRetain(str)`并返回原始字符串(正如MartinR所说). (2认同)
  • 实施细节无关紧要.`copy`返回一个保证是原始对象副本的实例,该对象的状态与所述对象隔离(但其包含的对象状态可能不是孤立的 - 集合是浅拷贝).无论副本是否是同一个实例,同一个类的不同实例或不同类的实例都是无关紧要的.要回答OP的问题,返回的对象有+1保留计数(可能是1,可能是42,可能是-1,不重要).你需要在某个地方发布它.假设其他任何事都不正确. (2认同)

bbu*_*bum 5

copy返回一个对象,该对象是对象的语义[浅]副本(1).该copy方法返回的是实现细节; 它可能会返回同一个对象,它可能会返回同一类的不同实例,或它甚至可能返回不同的类的实例.

无所谓.

重要的是,在手动保留/释放下,返回的对象的保留计数为+1.不是1,而是+1.它实际上可能是1,42,981或-1.无所谓.

重要的是,如果要将对象放回系统,必须平衡保留与某个releaseautorelease某个地方.这实际上可能不会导致其被解除分配; 这是一个无关紧要的实现细节(无论如何,直到优化时间).

(1)语义[浅]复制意味着返回的对象是有效的浅拷贝.复制对象中包含的状态(但不包含在对象中包含的对象内 - 即浅部分)在原始对象更改状态时不会更改.对于一个可变对象,copy实际上必须创建一个可以包含原始状态的某个对象的新实例 - 很可能是一个不可变的变体类.

对于不可变对象,该copy方法可以简单地实现为return [self retain];.或者,在静态NSStrings(NSCFStrings)的情况下,它可能只是return self;作为retain/release/autorelease对这些字符串的no-ops.