views:

725

answers:

3

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; 
}
+2  A: 

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

Bryan Kyle
Ah, a faster typer than I am :-)+1 seems very likely to be the autoreleased variables
frenetisch applaudierend
argh...they were never allocated to begin with`currentYear = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%d", year]];``nextYear = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%d", year+1]];`
rson
rson, although that will work, it is allocating an extra string for no reason. See my answer.
gerry3
+1  A: 

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];
}
Bryan McLemore
A: 

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.

gerry3
Thanks gerry...I'm still trying to get a handle on the whole garbage collection aspect of objective-c...this is a good tid-bit and what I'm now using in lew of my previous comment.
rson
Actually, this is (manual) memory management. With garbage collection, things can be a lot easier, but the iPhone does not currently support it.
gerry3