我一直在玩核心数据,并开始编写一些方法来查询不同的日期范围的数据。我的核心数据模型非常简单(实体名为Smoke,带有一个字段 - 时间戳(类型为日期)。诊断autorelease错误(EXC_BAD_ACCESS)
当我执行我的代码时,正确的计数会返回,但我得到一个autorelease错误 - 我使用NSZombies跟踪它下面的方法:
- (NSUInteger)retrieveSmokesForUnit:(NSCalendarUnit)unit
{
NSDate *beginDate = [[NSDate alloc] init];
NSDate *endDate = [[NSDate alloc] init];
[self rangeForUnit:unit containingDate:[NSDate date] startsAt:&beginDate andEndsAt:&endDate];
NSInteger count = [self numberOfSmokes:beginDate toDate:endDate];
[beginDate release];
[endDate release];
return count;
}
所以我得到的概念 - 我释放的NSDate对象BEGINDATE日期和结束日期过很多次 - 但为什么这种情况发生我认为规则是,当你用ALLOC实例,你呢?使用版本?我没有明确地在代码中的任何其他地方发布它们,所以一定会有幕后的事情发生。如果有人可以指引我朝着正确的方向发展,那将是非常好的!
以下是涉及的其他方法,因为问题必须在这些方面。我认为这与我如何传递指向日期的指针有关?
最初的电话,称在视图控制器
- (IBAction)cigButtonPressed
{
NSUInteger smokes = [[DataManager sharedDataManager] retrieveSmokesForUnit:NSWeekCalendarUnit];
NSLog(@"Count test = %i", smokes);
}
这卡列斯的方法张贴的问题,进而调用的开头:
- (NSUInteger)numberOfSmokes:(NSDate *)beginDate toDate:(NSDate *)endDate {
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Smoke" inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
//Create predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(timeStamp >= %@) AND (timeStamp < %@)", beginDate, endDate];
//Setup request
[request setEntity:entity];
[request setPredicate:predicate];
NSError *error;
NSUInteger smokes = [self.managedObjectContext countForFetchRequest:request error:&error];
NSLog(@"Number of smokes retrieved: %d", smokes);
[request release];
return smokes;
}
谢谢!
编辑 - 省掉了一个相关的方法:
- (void)rangeForUnit:(NSCalendarUnit)unit containingDate:(NSDate *)currentDate startsAt:(NSDate **)startDate andEndsAt:(NSDate **)endDate {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar rangeOfUnit:unit startDate:&*startDate interval:0 forDate:currentDate];
*endDate = [calendar dateByAddingComponents:[self offsetComponentOfUnit:unit] toDate:*startDate options:0];
[calendar release];
}
当我有一个自动的问题(其产生令人沮丧的一点调试信息)我已经成功通过创建缩小它与耗尽代码块周围的自动释放池(注意保留必须保留在“漏极”上的任何值)。你最终会下到一个小地方,在那里你的泳池会引发问题。 –
我可以缩小到retrieveSmokesForUnit中的[beginDate release]和[endDate release]行...如果我删除这些,它运行良好,没有崩溃... – Jim
啊,用添加的代码,问题是漂亮的明显。您创建(保留的)日期对象,然后使用rangeForUnit中的自动发布版本覆盖它们,然后释放自动发布的版本(保留原始日期对象泄漏,顺便说一下)。 –