views:

346

answers:

3

I'm starting to understand memory management better in objective-c, but there's something I don't understand. This is a property declaration:

@property (nonatomic, retain)UILabel *myLabel;

and this is its unseen synthesized setter (I think):

- (void)setMyLabel:(UILabel *)newValue {
    if(myLabel != newValue) {
        [myLabel release];
        myLabel = [newValue retain];
    }
}

Which saves you all the work of retaining and stuff every time, but say I set my property for the first time, its hasn't been allocated yet so its reference count is 0, right? So I do

UILabel *tempLabel = [[UILabel alloc] init];
self.myLabel = tempLabel;
[tempLabel release];

I'm not really sure what happens there, when it releases nothing , but say the property already has a value, and we set it. In the setter, first it gets released. So doesn't that make it dissapear? If its reference count is one, and then in the setter its released, how does it stay around to be set to the retained new value?

Thanks!!

+4  A: 

I think you are confusing objects and references. A property is a reference to an object, not the object itself. When you set or unset a property it sends retains and releases to the objects it points to, but the reference itself is part of the object that the property is in (in this case self).

It might be useful to read up on things like pointers and lvalues.

Louis Gerbarg
Thanks that makes sense.
Mk12
A: 

I'm relatively new to Objective-C also, but would like to try to answer this to re-affirm my understanding.

say I set my property for the first time, its hasn't been allocated yet so its reference count is 0, right?

Yes, the retain count is 0.

In the setter, first it gets released. So doesn't that make it dissapear?

It subtracts 1 from the retain count of myLabel. If the retain count of myLabel reaches 0, the data or object that the myLabel variable is pointing to will be freed from memory.

If its reference count is one, and then in the setter its released, how does it stay around to be set to the retained new value?

In that scenario, the data myLabel is pointing to will be freed (retain count will be 0) and myLabel will then point to nil (it's empty). The variable is set in the class and will always be available to accept messages to that setter, so the new data can be assigned to myLabel whether myLabel's retain count is 0 or 100.

Greg
Technically, it's best to not think about absolute retain count, but instead think of whether you have an ownership stake in the object. If an object's retain count reaches 0, it is deallocates. Autoreleased objects (which may have retain count of 1 and later drop to 0) are different than what you're explaining in your first point. And as Louis points out, ivars (variables/references) don't have retain counts — objects do.
Quinn Taylor
A: 

The initial value of myLabel is nil, so your first assignment to the property, ie

self.myLabel = tempLabel;

will release nil, ie [nil release]. In Objective C, sending a message to nil is a no-op, so this will do nothing.

Similarly, in your dealloc method, you should have:

[myLabel release];

Which will release the myLabel if the property has ever been assigned, balancing out the [newValue retain] in the setter. If the property has never been assigned, then it will still be nil, and again the [nil release] will be a no-op.

Read the memory management rules for the exact rules on when you need to retain/release objects.

The object will "disappear" (ie, be deallocated) when all ownerships on it have been relinquished. That is, when (or shortly after) all alloc/copy/new calls have been balanced with release/autorelease calls.

Peter N Lewis