user306766
user306766

Reputation:

NSDate & Memory management

memory management still gives me grief. This time it is an NSDate iVar that I init using

NSDate *myNSDate = [[NSDate date] firstDayOfMonth];

with a method call to

- (NSDate *)firstDayOfMonth {
    NSDateComponents *tmpDateComponents = [[NSCalendar currentCalendar]
                                            components:NSYearCalendarUnit | NSMonthCalendarUnit | NSEraCalendarUnit | NSWeekCalendarUnit | NSWeekdayOrdinalCalendarUnit
                                            fromDate:self];
    [tmpDateComponents setDay:1];
    [tmpDateComponents setHour:0];
    [tmpDateComponents setMinute:0];
    [tmpDateComponents setSecond:0];
    return [[NSCalendar currentCalendar] dateFromComponents:tmpDateComponents];
}

At the end of the init call the retain count is at 1 (Note the iVar is not defined as a property).

When I step into the viewWillAppear method the myNSDate has vanished. I tried to do an explicit retain on it, but that only lasts until I update the iVar using the above method again.

I though - ok - I add the retain to the return of the function, but that makes the leak analyser throw up an error.

What am I doing wrong?

Upvotes: 0

Views: 266

Answers (1)

Dave DeLong
Dave DeLong

Reputation: 243146

Your method firstDayOfMonth is correct as it is given in your question. However, the return value of that method is an autoreleased date, which means that if you don't retain the return value somewhere else, it will disappear.

So you need to do something like this (assuming your ivar is named firstDayOfMonth:

- (id) init {
  if (self = [super init...]) {
    ...
    [self setFirstDayOfMonth:[[NSDate date] firstDayOfMonth]];
  }
  return self;
}

- (void) setFirstDayOfMonth:(NSDate *)newFirstDay {
  [firstDayOfMonth release];
  firstDayOfMonth = [newFirstDay retain];
}

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

In this, you're explicitly retaining the return value (but also making sure to release the old value so you're not leaking memory). Now your date object will live until you set a new date, or the object is deallocated and the date is destroyed in the dealloc method.

Upvotes: 1

Related Questions