使用NSTimeInterval进行无法解释的崩溃

时间:2011-11-02 13:55:25

标签: objective-c nsdate nstimeinterval

我似乎无法弄清楚一段代码更改导致我的应用程序出现硬崩溃而没有太多调试痕迹的错误。

这是原始方法

+ (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;
}

该方法设置了一些变量,因此我可以查询数据库以查找从现在到未来24小时之间有时间戳的所有记录。我需要更改方法以查询从现在到明天(第二天午夜)之间的时间戳的所有记录,因此我根据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;
}

然而,当这两行:

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

包含应用程序崩溃。我通过评论它们等将它缩小到这两行。

我完全不知道出了什么问题。

2 个答案:

答案 0 :(得分:1)

由于你的崩溃堆栈跟踪在_CFAutoreleasePoolPop中的objc_msgSend中,你可以推断它可能是一个过度发布的错误。

这一行错了:

[components release], components=nil;

你没有那里的组件。查看给您的方法的名称。你过度释放了它。

答案 1 :(得分:0)

正如rob mayoff所说,第二个版本是错误的(第一个版本是必要的)。试试这个:

+ (NSArray *)currentReservations {
    NSDate *today = [NSDate date];
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
    [components setDay:1];  // tomorrow
    NSDate *tomorrow = [gregorian dateByAddingComponents:components toDate:today options:0];
    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
    components = [gregorian components:unitFlags fromDate:tomorrow];
    [components setHour:0];
    [components setMinute:0];
    NSDate *tomorrowMidnight = [gregorian dateFromComponents:components];
    [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;
}