Overriding @property setters with ARC for @property with 'copy'

automatic-ref-counting, ios, objective-c

Solution

You should do the second.

If you override the setter you are taking control of the semantics of copy vs non copy. ARC will do the correct thing with regards to inserting retain/releases with the assignment but it won't call `copy` for you

My source? Test it

@interface UnicornWithCopyCall : NSObject

@property (nonatomic, copy) NSString *name;

@end

@implementation UnicornWithCopyCall

- (void)setName:(NSString *)name
{
  _name = [name copy];
}

@end

@interface UnicornWithOutCopyCall : NSObject

@property (nonatomic, copy) NSString *name;

@end

@implementation UnicornWithOutCopyCall

- (void)setName:(NSString *)name
{
  _name = name;
}

@end

Then exercise this with

UnicornWithCopyCall *unicorn = [[UnicornWithCopyCall alloc] init];
unicorn.name = name;

NSLog(@"%p %p", name, unicorn.name);

UnicornWithOutCopyCall *unicornWithOutCopyCall = [[UnicornWithOutCopyCall alloc] init];
unicornWithOutCopyCall.name = name;

NSLog(@"%p %p", name, unicornWithOutCopyCall.name);

Without the copy call the pointers are identical, whereas with the copy call you get a new object, which is a copy.

Problem

``` @interface Unicorn @property (nonatomic, copy) NSString *name; @end ``` Is it like this? ``` - (void)setName:(NSString *)name { _name = name; } ``` Or is it like this? ``` - (void)setName:(NSString *)name { _name = [name copy]; } ```

Original source