Search code examples
objective-cnsdatenstimeinterval

Unexplained crash with NSTimeInterval


I cant seem to figure out a bug with a piece of code change that is causing a hard crash in my app without much of a debugging trail.

Here is the original method

+ (NSArray *)currentReservations {
    NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
    double futureTimeframe = interval + SecondsIn24Hours;
    NSArray *reservations = [Reservation findWithSql:@"select * from Reservation where timestamp < ? and timestamp > ?" withParameters:[NSArray arrayWithObjects:[NSNumber numberWithDouble:ceil(futureTimeframe)], [NSNumber numberWithDouble:floor(interval)], nil]];
    return reservations;
}

The method sets a few variables so I can query the database to find all records that have timestamps between now and 24 hours into the future. I need to change the method to query for all records with timestamps between now and tomorrow (midnight of the next day), so I updated the code to this based on this other stackoverflow question

+ (NSArray *)currentReservations {
    NSDate *today = [NSDate date];
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    [components setDay:1];  // tomorrow
    NSDate *tomorrow = [gregorian dateByAddingComponents:components toDate:today options:0];
//    [components release];  // dont think we need this release, but it is in the example here: https://stackoverflow.com/questions/181459/is-there-a-better-way-to-find-midnight-tomorrow
    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
    components = [gregorian components:unitFlags fromDate:tomorrow];
    [components setHour:0];
    [components setMinute:0];
    NSDate *tomorrowMidnight = [gregorian dateFromComponents:components];
    [components release], components=nil;
    [gregorian release], gregorian=nil;


    NSTimeInterval interval = [today timeIntervalSince1970];
    NSTimeInterval tomorrowInterval = [tomorrowMidnight timeIntervalSince1970];

    NSArray *reservations = [Reservation findWithSql:@"select * from Reservation where timestamp < ? and timestamp > ?" withParameters:[NSArray arrayWithObjects:[NSNumber numberWithDouble:tomorrowInterval], [NSNumber numberWithDouble:floor(interval)], nil]];
    return reservations;
}

However, when these two lines:

    NSTimeInterval interval = [today timeIntervalSince1970];
    NSTimeInterval tomorrowInterval = [tomorrowMidnight timeIntervalSince1970];

are included the app crashes. I've narrowed it down to these two lines by commenting them out, etc..

I'm completely at a loss for what is wrong.


Solution

  • Since your crash stack trace is in objc_msgSend inside _CFAutoreleasePoolPop, you can deduce that it's probably an over-release bug.

    This line is wrong:

    [components release], components=nil;
    

    You don't own components there. Look at the name of the method that gave it to you. You are over-releasing it.