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

@interface Unicorn
@property (nonatomic, copy) NSString *name;
@end

This is true?

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

Or is that so?

- (void)setName:(NSString *)name
{
   _name = [name copy]; 
}
+4
source share
2 answers

You must do the second.

If you override the setter, you take control of the semantics of copying and without copying. ARC will do the right thing with respect to insert save / release with assignment, but will not call copyfor you

My source? Check him

@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 do 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 a copy call, the pointers are identical, whereas when you call the copy, you get a new object, which is the copy.

+9
source

. , , . , , , _name name , , , .

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

CocoaWithLove

- (void)setStringValue:(NSString *)aString
{
    if (stringValue == aString)
    {
        return;
    }
    NSString *oldValue = stringValue;
    stringValue = [aString copy];
    [oldValue release];
}
+3

Source: https://habr.com/ru/post/1527095/


All Articles