views:

47

answers:

2

Hi, am working my way through the "Beginning iPad Development" Apress book and have noticed that sometimes when the author is assigning values to a property they will use:

self.variable = value;

and other times, they will use:

variable = [value retain];

In both cases variable is a property defined as:

@property (nonatomic, retain) TYPE variable;

I wondered if anyone knew why this is done to help me better understand

Thanks, William

A: 

They are often equivalent memory-wise. The compiler turns self.variable = value into [self setVariable:value] which then calls the generated setter (if you're using @synthesize) and retains it for you.

cobbal
keep in mind though that you need to release the value if you retained it manually!
Toastor
You need to release it manually if you use the retain attribute on a property, too.
Echelon
thanks for the quick response. A second question has came from this when the [value retain] statement is used is the retain being placed on the variable "value" or what it is pointing at?
wibo
@wibo In objective-C all objects are "pointed at". `[value retain]` retains the object, then returns it to you.
cobbal
It only retains it if the property is defined as `(retain)`.
Dave DeLong
+2  A: 

One place where you use the second form is if you're defining your own setter method. You can't assign to self.variable there, because you'll call the setter recursively. So for example this is wrong:

-(void)setVariable:(TYPE*)value {
    if (value != variable) {
        [variable release];
        self.variable = [value retain]; // WRONG! Calls 
                                        // [self setVariable:[value retain]]
    }
}

This is right:

-(void)setVariable:(TYPE*)value {
    if (value != variable) {
        [variable release];
        variable = [value retain];
    }
}

Does that help?

Simon Whitaker
This has a potential bug: if you call `obj.var = obj.var` you might release and deallocate the object before you retain it again.
cobbal
thanks for the response I could see that being a nasty bug to track if it was in your code
wibo
cobbal: if you call `obj.val = ob.val` then `value != variable` will evaluate to false and the code inside the if block won't be called.
Simon Whitaker
@Simon Ah, missed that for some reason. I can still think of a bizarre edge case bug in the case of arrays of arrays, although it might be more academic than anything `obj.var = [obj.var objectAtIndex:0]`
cobbal