views:

71

answers:

3

Given the next code snippet:

...

- (void) setTotalAmount: (NSNumber*)input
{
    [totalAmount autorelease];
    totalAmount = [input retain];
}

- (void) dealloc
{
    [totalAmount release];
    [super dealloc];
}

...

What I want to understand how really we set value. We allocate local (instance) var and "retain" to input var. But what is "input"? Is it a pointer to real value? Or is it value itself? When we "retain" do we get a pointer to "input" or pointer to value or just the value?

And pretty same questions with dealloc and release. What actually "dies" here?

Thank you!

+3  A: 

It's clear that input is a pointer. You have declared its type in the argument list as NSNumber*.

input is a pointer to an object of type NSNumber. Internally, the object has an integer variable that holds the number of external references to it. Sending the retain message to an object will increment its reference count. Sending the release message will decrement the count. Sending the autorelease message will adds the object to the local autorelease pool which will keep track of autoreleased objects and sends the release message to them next time it drains. An object with reference count of 1 that receives a release message will get deallocated and its dealloc method will get called. You should release all the resources you hold when you are deallocated.

When you are setting a property, you want to release the old value and make sure the new value is kept around as long as the object itself is alive. To make sure the new value is kept around, you increment its reference count by 1 by sending it the retain message. To release the old object, you'll send it the release message. There's one subtle issue here. If the old value is the same as the new value, if you release the old value first and its retain count was 1, it'll get destroyed before you can increment it. That's why you should retain the new value before releasing the old one.

Mehrdad Afshari
A: 

input is the NSNumber

- (void) setTotalAmount: (NSNumber*)**input**

Which is called by doing something like this:

[object setTotalAmount:number];
Matt S.
No, `input` is a pointer to the NSNumber instance. The distinction is important to this question. And your example won't compile - you're showing `setTotalAmount` being called with an int argument, but that method's parameter is typed as a pointer to NSNumber.
erikprice
oh crap, I always do that!
Matt S.
+1  A: 

Assuming that you have instantiated an object of the above class named "myObject", you could set its totalAmount like this:

...

// get a new NSNumber object which will be autoreleased
NSNumber *amount = [NSNumber numberWithInteger:10];

// call the setter which will autorelease the previous value of
// totalAmount (if any), retain the object referenced by "amount"
// (so that object will no longer be deallocated when it's autoreleased),
// and reference that object from the totalAmount instance variable
myObject.totalAmount = amount;

...

Later, when "myObject" is deallocated, the object referenced by the totalAmount instance variable will be released (and deallocated if it was not retained anywhere else).

gerry3