0
votes

I'm working through Aaron Hillegass' book, specifically the lottery example. I had a question about the -setEntryDate: method; why do I have to retain date? The program still works without retaining it.

 -(void)setEntryDate:(NSCalendarDate *)date {
    [date retain];
    [entryDate release];
    entryDate = date;
}

But this still works fine:

-(void)setEntryDate:(NSCalendarDate *)date {
    entryDate = date;
}

So why is it correct that I have to retain date and then release entryDate?

4
Incidentally, your method name says "date" and your parameter is called "date," but the type appears to be an NSCalendar, which is not a date by any stretch of the imagination. Did you mean to use NSDate?Chuck
I actually meant NSCalendarDate, thanks for pointing that out.Brad

4 Answers

7
votes

It works for now, but if you were writing a larger program there is a possibility that, at some indeterminable point in the future, the object date points to would be released by whomever called setEntryDate. If that happened, it would be invalidated throughout the rest of the program. You are retaining this object in the class because that class now owns a reference to that object and needs to indicate that. By doing this, even if whatever class called setEntryDate were to release date, your class would still maintain a valid reference to it. Also, this is not just a regular old method you are writing. This is a setter, which has the specific responsibility of setting an instance variable on the class it belongs to. If you were writing a non-setter method, you may not have to retain the parameters. What I'm trying to say is that retaining method parameters is not always necessary; it just is in this case (and pretty much with all setters that deal with non-primitive types).

This is called "reference counting" and is explained in great detail here. For now, since you are just starting to learn, don't worry about reading that yet. When you start to get into more complex scenarios with memory management, then that guide is a very valuable piece of reading.

3
votes

Because you are claiming ownership of the object, and retain is how you do this. Incorrect code will sometimes happen to work correctly, but that is essentially just luck.

See the Cocoa memory management rules.

1
votes

Methods such as these are called accessor methods. They, as the name implies, allow variables to be retrieved, and set - specifically, they are called "getters" and "setters".

The convention (which, you will however see in later chapters of the book is more than a convention) is to call the "getter" for a variable, for example, an NSString called foo

- (NSString*)foo;

And the "setter":

- (void)setFoo:(NSString*)newFoo;

In the example above, the method is implemented to set the a new date value. Memory management is described in Chapter 4, but in short, the way Objective-C objects work is that they have a "retain count" - this is representitive of the number of references that the object has; when allocated, objects have a retain count of 1. The objects can then be sent the retain or the release message to increase or decrease the retain count respectively. A retain message implies that the object sending the message wants to use the object, so retains it. A release message implies that the object sending the message no longer wants to use the object, therefore decreasing the retain count. When the retain count of an object reaches 0, the object is deallocated. In this way, memory leaks are avoided.

The reason that date is retained and entryDate is released, is that date is the new object that you want to "know about"; you are therefore claiming ownership of it by retaining it. The entryDate variable points to the current date object, but since you are setting it to be a new value, you no longer need to know about it; therefore you release it; this prevents a memory leak, since you will have originally retained this variable.

As I said before, once reading Chapter 4: Memory Management, the concept will become much more clear. For now, just accept it and understand the reasoning behind it when it is explained.

1
votes

If you learn by videos better, Stanford University has published some videos on the iPhone development which also cover Cocoa and Objective-C to a certain extent. Check out lecture 3, it makes a good overview on memory management, with examples and discussion.