我想知道,引用计数增加的方式是什么.我知道,alloc / init和retain增加引用计数,’copy’是否也将引用计数增加到’1’?
谢谢.
解决方法
所以事实上它并没有真正“增加1的引用计数”,而是创建一个新对象,引用数为1作为任何新分配的对象,并使其具有与原始对象相同的属性/ ivar值.
因此,假设你有一个具有属性名称,姓氏和年龄的Person类,如果你需要自己实现复制方法,它会看起来像这样:
-(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).这就是为什么在一个对象上调用副本遵循与retain或alloc相同的规则,关于需要调用release或autorelease以在某些时候平衡refcount
请注意,有一些异常/特殊情况,特别是对于某些被称为“不可变”的类,如NSArray或NSString.在这种情况下,制作一个副本(也就是一个不同的对象实例)是原始的克隆,而原件不能被修改,是不合理的,并且可以进行优化是合理的.
因此,在像NSArray和NSString等一些情况下,复制方法可能只是实现了一个简单的保留,因为行为将是相同的,因为你无法修改原始(也没有副本),因为这些是不可变的类本质上.
当然,mutableCopy的实现(例如从NSArray获取NSMutableArray)执行真正的副本而不是简单的保留,并且可变子类(如NSMutableString和NSMutableArray)中的copy方法的实现也做了真正的复制,但是对于请求不可变对象的不可变副本的情况,分配不同实例的点通常是无用的并且消耗内存,因此实现与保留相同.
但是所有这些可能的优化都不会改变行为(因为类是不可变的)也不会改变内存管理策略(因为你仍然需要释放副本返回的对象)