Question

This is an example from The Objective-C 2.0 Programming Language. I was just wondering, in the setter at the bottom, can I use value = [newValue retain] instead of value = [newValue copy] ?

    @interface MyClass : NSObject

{

    NSString *value;

}

@property(copy, readwrite) NSString *value;

@end



// assume using garbage collection

@implementation MyClass

@dynamic value;



- (NSString *)value {

    return value;

}



- (void)setValue:(NSString *)newValue {

    if (newValue != value) {

       value = [newValue copy];

    }

}

@end
Was it helpful?

Solution

The quickest and safest thing to do would be to add @synthesize value to the top of your implementation, and the compiler will automatically generate these methods.

The issue of copy vs. retain hinges on the fact that you may be passed in a NSMutableString, which would change its value. If you have a setter for an 'immutable' type (string, set, array, dictionary), you need to use copy semantics. At first this may seem counterintuitive (why make a copy if it's immutable?) but the thing to realize is that your class wants to assume it is immutable, and what's passed in may not actually be immutable.

NSMutable classes implement the copy selector by returning an immutable version of what they represent. The immutable classes (NSString, etc) implement copy with a retain call. That is to say, they are very fast.

Your setter also needs to release value before assigning it a new value. The proper code is:

-(void)setValue:(NSString*)newvalue
{
    if (value != newvalue)
    {
        [value release];
        value = [newvalue copy];
    }
}

If you have complete control over all the classes that may call setValue: and are absolutely sure you won't be passing in NSMutableString, you can use retain, but it's best practices to use copy.

OTHER TIPS

It depends. If you use [newValue retain], another object may change the value of this NSString pointer. Normally, you do not like to have this behaviour.

No, your interface says copy. If somebody passes in an NSMutableString, you will get very different results from the two methods.

setter method:

  -(void)setValue:(NSString*)newvalue{
        if (_value != newvalue)
        {
            [_value release];
            _value = nil;
            _value = [newvalue copy];

        }
   }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top