Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C immutable object copyWithZone: ARC-compatible realization

As I assumed, this should work's fine for immutable object under ARC:

- (id) copyWithZone:(NSZone *)zone {
    return self;
}

But if I need deep copy, I should write something like this:

- (id) copyWithZone:(NSZone *)zone {
    Immutable *copy = [[Immutable alloc] initWithStr:str];
    return copy;
}

So, If I assumed right, ARC would understand situation (1) and (2) and make right decision about "+1" for references.

Am I right ?

like image 228
dmitrynikolaev Avatar asked Feb 03 '12 10:02

dmitrynikolaev


People also ask

What is copywithzone?

Returns a new instance that's a copy of the receiver.

Does copy increase retain count?

No, a copied object will have a retain count of 1, just like a newly initialized object.


2 Answers

Automatic reference counting, as stated in the specification, obeys standard Cocoa naming practices. This means that methods with the prefixes init, copy, and new are assumed to return objects that the caller owns (+1 reference count). Therefore, if you return an object from one of those methods, ARC automatically handles it this way since you no longer can explicitly retain it.

The one problematic case around this that Apple has pointed out would be a third-party framework using manually reference counted code where the authors did not follow standard naming conventions. An example they gave was a method returning an autoreleased string called copyRightString. This will be overreleased on ARC, because it will assume that a +1 reference counted object is returned from such a method.

You can force ARC to treat this method in a special manner using a modifier like the following:

-(NSString*) copyRightString NS_RETURNS_NON_RETAINED;

Mugunth Kumar has a little more detail on this in his ARC migration writeup.

like image 42
Brad Larson Avatar answered Oct 01 '22 23:10

Brad Larson


Seems I'm right: I can't find any concrete documentation on topic, but I create separate test project with ARC turned off, then choose migrate to ARC. Here is code without ARC:

- (id) copyWithZone:(NSZone *)zone {
    return [self retain];
}

This is what I got after migration:

- (id) copyWithZone:(NSZone *)zone {
    return self;
}

It's a magic how ARC works sometimes, but seems we should just believe it will doing it's job well. :-)

like image 109
dmitrynikolaev Avatar answered Oct 01 '22 23:10

dmitrynikolaev