Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: Copy property

Tags:

ios

I couldn't get the right answer for this question. If it is found duplicate, please make it duplicate with the right reference link.

I wanted to know, what are the ways the reference count is incremented. I know, alloc/init and retain increases the reference count, does 'copy' also increases the reference count to '1' ?

Thanks.

like image 993
Daisy Avatar asked Oct 10 '12 09:10

Daisy


1 Answers

copy creates a new object which is, as the method name suggest, a carbon copy of the receiver (well in fact it depends of the implementation of the copy method in each class, but that's the aim of the method anyway).

So in fact it does not really "increase the reference count of the by 1" but it rather create a new object, with a refcount of 1 as any newly allocated object, and make it have the same property / ivar values as the original.

So imagine you have a Person class with the properties name, surname and age, if you needed to implement the copy method yourself it would look sthg like this:

-(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;
}

Note that in this case, if you modify the copy later, the original is not modified, because it is a different instance.

With this principle, the original object does not have its refcount incremented by one, but you have a new object whose refcount is one (as if you just did alloc/init to create this new object yourself) and you still have to release or autorelease it at some point yourself (if you are not using ARC). That's why calling copy on an object obey the same rules as retain or alloc regarding the need to call release or autorelease to balance the refcount at some point


Note that there is some exceptions / special cases, especially for some classes that are known as "immutable", like NSArray or NSString. In such cases, it is reasonable to thingk that making a copy (aka a different object instance) that is a clone of the original, whereas the original cannot be modified, is not really efficient, and can be optimized.

So in cases like NSArray and NSString and some other, the copy method may simply implemented to do a simple retain as the behavior will be the same as you can't modify the original (and neither the copy) because these are immutable classes by nature.

Of course, the implementation of mutableCopy (to get an NSMutableArray from an NSArray for example) do a real copy and not a simple retain, and the implementation of the copy method in the mutable subclasses like NSMutableString and NSMutableArray do a real copy too, but for the case that request an immutable copy of an immutable object, the point of allocating a different instance is generally useless and memory-consuming and is thus implemented the same as a retain.

But all this probable optimization does not change neither the behavior (because the classes are immutable) nor the memory management policy (as you still need to release the object returned by copy)

like image 93
AliSoftware Avatar answered Oct 12 '22 23:10

AliSoftware