views:

608

answers:

4

I'm having a lot of issues with NSDate objects being prematurely deallocated. I suspect that the issues may be related to the way that I deal with the objects returned from NSDate convenience methods. I think that my showDate property declaration in the JKShow class should be "retain", but changing it to assign or copy seems to have no effect on the issue.

JKShow *show; 
NSDate *date;
NSMutableArray *list = [[NSMutableArray alloc] init];

// Show 1
show = [[JKShow alloc] init];
//...
date = [gregorian dateFromComponents:dateComponents];
show.showDate = date;
[list addObject:[show autorelease]];

// Show 2
show = [[JKShow alloc] init];
//...
date = [gregorian dateFromComponents:dateComponents];
show.showDate = date;
[list addObject:[show autorelease]];

UPDATE

The issue was not in the code copied here. In my JKShow init method I was not retaining the date returned from the NSDate convenience method. Thanks for your help, everyone.

+2  A: 

The date returned from dateFromComponents should be in the autorelease pool, so you are correct that your showDate property should be "retain". In fact it should be anyway (unless you specifically want "copy").

From the code you have shown it looks like you are giving ownership of your show object entirely to the list (as you're setting autorelease on them as you add them). Are you saying that the date objects are being deallocated before the show objects are coming out of the list (or the list is being deallocated)?

Also, are you using synthesised properties, or are you writing them by hand? If the latter, what is your setShowDate property method like?

You can also try logging the retainCount of the date object at different places (although I always find that autorelease really complicates that).

Phil Nash
+2  A: 

If showDate is a retain property that should be sufficient, given the code you have posted. Something else (probably in JKShow's implementation) may not be correct.

If you want to figure out what is going on, you can use Instruments to see examine the objects lifespan. You need to run it with the allocation tool set to remember retains and releases. By default it is set up that way if you run the leaks performance tool.

When you run Instruments like that it will record all object life spans, and the backtrace for every retain and release issued against them. If you look through the objects, find one of your dates, and look at all the retains and releases you should be able to determine where the spurious release is happening.

Louis Gerbarg
I'm looking into this now, but as long as I've got you here, how do you unlink instruments from your project? In the past I've restarted xcode, but it seems like there is bound to be a better way.
kubi
When you select "Go" it does whatever you did last (Run, Debug, Leaks, etc). Just select Run explicitly and the next time you hit Go it will runt he app without Instruments.
Louis Gerbarg
A: 

The code you showed has no premature-release problems. In fact, it will leak the array and everything in it, because it doesn't release the array.

Are you running with the garbage collector turned on?

Is list an instance variable or static variable, or is it a local variable?

Peter Hosey
The list object is used later and I'm not having any problems with it. No garbage collection. List is a local variable.
kubi
A: 

I figured it out, thanks for all your help, but the problem was outside of the code I posted here. I was not retaining the NSDate I created in my init method. Unfortunatly the crash didn't occur until after I had created the two new NSDate objects, so I was totally barking up the wrong tree.

kubi
Probably a good idea to post your update as an edit to the original question. Glad you found it though - hunting these things down is always a pain.
Phil Nash