You're not retaining the last variable. If you don't do this it will become garbage when the init method exists.

So you do this:

last = [[NSDate date] retain];
[last addTimeInterval: -1.0];

Read about Cocoa memory management and read it very carefully. To summarize:

if you init alloc, you must release
if you retain, you must release
if you autorelease, you don't do anything
if you want to reuse autoreleased objects, you retain, and release when you are done with them

Taxxodium Wrote:That's a memory leak, you don't need to retain now, since you are only using it in this method.

Instead do this:

NSDate *now = [NSDate date];
[last release];
last = [now retain];

Wait, you said you don't need to retain it, but you retain it there? Regardless, it should be on the autorelease pool, so it would need to be retained if you want to keep it around. Retaining it where he did makes no difference from where you're retaining it. However, there will be a memory leak since there's no dealloc method releasing last.

Anyways, it looks like your problem is you need to retain last in your init method, since, as I said, it's on the autorelease pool. When doing memory management in Cocoa, I usually try to keep it as close to how I do it in C or C++ as possible. Here's the tricks I use:
If I use an object created without alloc, and I only use it one time, I just leave it be.
If I'm passing an object into a method for another object that's supposed to store its own copy (such as passing in a string for a file name), I just copy it rather than dealing with retaining.
If I insert an object into an array or other Cocoa data structure that's only meant to go in that data structure, I immediately release it. (since it retains the object)
Otherwise, I never call retain, and I release only if the object is destroyed or is replaced by another object.

akb825 Wrote:Anyways, it looks like your problem is you need to retain last in your init method, since, as I said, it's on the autorelease pool. When doing memory management in Cocoa, I usually try to keep it as close to how I do it in C or C++ as possible. Here's the tricks I use:
If I use an object created without alloc, and I only use it one time, I just leave it be.
If I'm passing an object into a method for another object that's supposed to store its own copy (such as passing in a string for a file name), I just copy it rather than dealing with retaining.
If I insert an object into an array or other Cocoa data structure that's only meant to go in that data structure, I immediately release it. (since it retains the object)
Otherwise, I never call retain, and I release only if the object is destroyed or is replaced by another object.

Sounds like some good rules to go by. I may try those approaches but I really need to get a better understanding on Cocoa memory management. So I will probably spend some time reading through that information.

On another note. I have an application up and running that I need to get some opinions on. I know people don't really trust files that are linked here but I hope that some one will download and give me some feedback. I will be posting about it in another thread, because I have some questions/issues I need to get worked out that I will include in the post.

Gerry

Quote:There is a name for people who are not excited about their work--unemployed.

The problem is that your last variable holds an autoreleased value. Whenever you get an NSObject out of a method that is not -alloc...; or -new;, the standard behavior is to get an autoreleased object. This means if you want to keep it, you have to retain it. That means you're getting autoreleased objects out of -addTimeInterval; and +date;.

The basic assumption in Cocoa is that if you didn't -alloc; or -new; it, then it is autoreleased when you get it. Whether or not does in fact have a retain count of 0, doesn't matter. If you want to stick it in a semi-permanent variable like last, you're going to have to retain it. (in your original code you missed the first retain and you lose the object when the autorelease pool dumps it).

EDIT: Yes, your fix is the correct solution.
Might I add though that you neglect to clean up in a destructor.
Since you retain the NSDate in this object you should release it when your Object deallocs.

Ok, these last few posts brought a question to me about retain and release.

Looking at just this portion of the code and assuming everything else has been initialized correctly.

Code:

- (void) doWork
{
[b]// If I retain "now" here, I may run doWork several times
// before I get to "[last release];" below, which is really
// releasing a previously retained "now" object.[/b]
NSDate *now = [[NSDate date] retain];

- (void) doWork
{
NSDate *now = [[NSDate date] retain]; //<-- object B
// object B will always be a new NSDate instance in this method.
// it's never the same one, and if you retain it without referencing it, you are leaking.

// doMoreWork
[last release]; //<-- object A
last = now; //<-- object B
}
//<-- you forget that there's an implied else here.
// if the above if statement evaluates to false, you're leaking object B.
// when this method returns, if you haven't set last to now, you won't have a reference to now no matter what and it just sit in memory.

}

The best thing to do is, if you retain an object, immediately set an instance variable to reference it. Don't forget though, that whatever was in that instance variable should be released first if it references something you retained earlier.

kelvin Wrote:The best thing to do is, if you retain an object, immediately set an instance variable to reference it. Don't forget though, that whatever was in that instance variable should be released first if it references something you retained earlier.

Thanks for adding that extra explanation. It really helps me understand. Incidentally, I ran this some portion of code with NSLog statements displaying the retainCount for "now" as the application was running. I could see that there was always one extra count for it when I retained outside of the if statement and did not release every time. So that gave me kind of a visual of what was going on.

Gerry

Quote:There is a name for people who are not excited about their work--unemployed.