Необъяснимый сбой с 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 часами в будущем. Мне нужно изменить метод для запроса всех записей с отметками времени между настоящим и завтрашним днем ​​(полночь следующего дня), поэтому я обновил код на основе другой вопрос о переполнении стека

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

включены приложение аварийно завершает работу. Я сузил его до этих двух строк, закомментировав их и т.д.

Я совершенно не понимаю, что не так.


person cpjolicoeur    schedule 02.11.2011    source источник
comment
Что вы имеете в виду под вылетом приложения? Каким образом? Какую трассировку стека вы получаете?   -  person Jim    schedule 02.11.2011
comment
при запуске в симуляторе просто жесткий сбой в основном цикле   -  person cpjolicoeur    schedule 02.11.2011
comment
вам нужно получить обратную трассировку (введите bt в консоли отладки), сбои никому не помогут решить вашу проблему   -  person jrturton    schedule 02.11.2011
comment
О, и вам действительно нужен этот закомментированный релиз, или вы сливаете исходное распределение components.   -  person jrturton    schedule 02.11.2011
comment
вот трассировка: gist.github.com/4cedf2cef066a3a57cb6   -  person cpjolicoeur    schedule 02.11.2011
comment
Хм, это не очень полезно (мне во всяком случае). Я не могу не думать, что ваш сбой происходит из-за того, что возвращается из вашего findWithSQL, а не из-за строк интервала времени - если вы прокомментируете эти строки, я думаю, вы ничего не получите, так что никакого сбоя. Я не вижу ничего плохого в опубликованном вами коде, бите findWithSQL:, с которым я не знаком, поэтому мои подозрения, естественно, падают на него. Если вы установите точку останова и выполните ее с помощью отладчика, вы можете получить больше информации.   -  person jrturton    schedule 02.11.2011


Ответы (2)


Поскольку ваша трассировка стека сбоя находится в objc_msgSend внутри _CFAutoreleasePoolPop, вы можете сделать вывод, что это, вероятно, ошибка перевыпуска.

Эта строка неверна:

[components release], components=nil;

У вас там нет компонентов. Посмотрите на название метода, который вам его дал. Вы чрезмерно выпускаете его.

person rob mayoff    schedule 02.11.2011

Как сказал Роб Мэйофф, второй релиз неверен (в то время как первый необходим). Попробуйте это вместо этого:

+ (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;
}
person MrMage    schedule 02.11.2011