tableView: titleForHeaderInSection: causing crash

2.8k Views Asked by At

For some reason, the tableView: titleForHeaderInSection: method is causing the application to crash without giving any details as to why. I know it is this method because when I comment it out, the table loads, just without headers obviously.

- (void)viewDidLoad {
    [super viewDidLoad];

    NSArray *monthArray = [NSArray arrayWithObjects:@"January", @"February", @"March", @"April", @"May", @"June", @"July", @"August", @"September", @"October", @"November", @"December", nil];

 NSCalendar *calendar= [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
 NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit;
 NSDate *date = [NSDate date];
 NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:date];

 NSInteger year = [dateComponents year];
 NSInteger month = [dateComponents month];

 currentYear = [NSString stringWithFormat:@"%d", year];
 nextYear = [NSString stringWithFormat:@"%d", year+1]; 

 [dateComponents setMonth:month];

 currentYearMonths = [[NSMutableArray alloc] init];
 nextYearsMonths = [[NSMutableArray alloc] init];

 for(uint i=month-1; i<=11; i++){
  [currentYearMonths addObject:[monthArray objectAtIndex:i]];
 }
 for(uint i=0; i<month-1; i++){
  [nextYearsMonths addObject:[monthArray objectAtIndex:i]];
 }

 [calendar release];
}


- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
 NSString *sectionHeader = nil;

 if(section == 0) {
  sectionHeader = currentYear;
 }
 if(section == 1) {
  sectionHeader = nextYear;
 }  
 return sectionHeader; 
}
3

There are 3 best solutions below

0
On BEST ANSWER

You're missing a few retain statements look below where you set currentYear and nextYear to see what should fix it.

- (void)viewDidLoad {
    [super viewDidLoad];

    NSArray *monthArray = [NSArray arrayWithObjects:@"January", @"February", @"March", @"April", @"May", @"June", @"July", @"August", @"September", @"October", @"November", @"December", nil];

    NSCalendar *calendar= [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit;
    NSDate *date = [NSDate date];
    NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:date];

    NSInteger year = [dateComponents year];
    NSInteger month = [dateComponents month];

    currentYear = [[NSString stringWithFormat:@"%d", year] retain];
    nextYear = [[NSString stringWithFormat:@"%d", year+1] retain]; 

    [dateComponents setMonth:month];

    currentYearMonths = [[NSMutableArray alloc] init];
    nextYearsMonths = [[NSMutableArray alloc] init];

    for(uint i=month-1; i<=11; i++){
        [currentYearMonths addObject:[monthArray objectAtIndex:i]];
    }

    for(uint i=0; i<month-1; i++){
        [nextYearsMonths addObject:[monthArray objectAtIndex:i]];
    }

    [calendar release];
}
2
On

As the others said, the objects referenced by your instance variables were not being properly retained.

To be clear, the "convenience" methods you were using to get your strings do allocate new strings. They also put the new objects in an autorelease pool.

For example, using a "convenience" method:

currentYear = [NSString stringWithFormat:@"%d", year];

is the same as:

currentYear = [[[NSString alloc] initWithFormat:@"%d", year] autorelease];

Since you want to retain these string objects, you can just use:

currentYear = [[NSString alloc] initWithFormat:@"%d", year];

but you could also do this:

currentYear = [[NSString stringWithFormat:@"%d", year] retain];

UPDATE
Also, keep in mind that you should be releasing the instance variables in the implementation of dealloc for the class.

2
On

I'm guessing that currentYear and nextYear are being released before your delegate method is being called. Try retaining those ivars.