Iphone 诊断自动释放错误(EXC\u错误访问)
我一直在玩弄核心数据,并开始编写一些方法来查询数据的不同日期范围。我的核心数据模型非常简单(实体名为Smoke,带有一个字段-timestamp(日期类型) 当我执行代码时,会返回正确的计数,但我会得到一个自动释放错误-我使用NSZombies跟踪到以下方法:Iphone 诊断自动释放错误(EXC\u错误访问),iphone,objective-c,memory-management,Iphone,Objective C,Memory Management,我一直在玩弄核心数据,并开始编写一些方法来查询数据的不同日期范围。我的核心数据模型非常简单(实体名为Smoke,带有一个字段-timestamp(日期类型) 当我执行代码时,会返回正确的计数,但我会得到一个自动释放错误-我使用NSZombies跟踪到以下方法: - (NSUInteger)retrieveSmokesForUnit:(NSCalendarUnit)unit { NSDate *beginDate = [[NSDate alloc] init]; NSDate *e
- (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和endDate的次数太多了——但是为什么会发生这种情况呢?我以为规则是当你用alloc实例化时,你使用release?我没有在代码中的任何其他地方显式发布它们,所以一定有一些事情在幕后发生。如果有人能告诉我正确的话t方向,那太好了
这里是涉及的其他方法,因为问题一定在这些方法中的某个地方。我想这与我如何传递指向周围日期的指针有关
初始调用,在视图控制器中调用
- (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;
}
在:
startDate
和endDate
是输出参数。它们不属于调用方所有,因此应不属于调用方
然后,在:
- (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;
}
发生以下情况:
+alloc
创建一个新的NSDate
对象,因此您拥有它。beginDate
指向这个新对象+alloc
创建一个新的NSDate
对象,因此您拥有它。endDate
指向这个新对象-rangeUnit:containingDate:startsAt:andEndsAt:
,将beginDate
和endDate
的地址作为参数传递。返回时,这两个变量指向该方法放置在其中的任何对象。您不拥有相应的对象(见上文),您泄漏了在步骤1和2中创建的两个NSDate
对象-release
发送给beginDate
和endDate
。您不拥有它们,因此不应该释放它们- 您不应该为
和beginDate
创建新对象,因为它们是由endDate
返回的,这会导致内存泄漏-rangeUnit…
- 您不应该释放
和beginDate
,因为您不拥有endDate
返回的对象,这会导致覆盖-rangeUnit…
- (NSUInteger)retrieveSmokesForUnit:(NSCalendarUnit)unit
{
NSDate *beginDate;
NSDate *endDate;
[self rangeForUnit:unit containingDate:[NSDate date] startsAt:&beginDate andEndsAt:&endDate];
NSInteger count = [self numberOfSmokes:beginDate toDate:endDate];
return count;
}
当我遇到自动释放问题(产生令人沮丧的小调试信息)时,我通过在代码块周围创建和排空自动释放池(注意保留必须在整个
排空过程中保留的任何值),设法缩小了问题的范围。您最终会进入一个小区域,您的池会引发问题。我能够将其缩小到retrieveSmokesForUnit中的[beginDate release]和[endDate release]行……如果我删除这些行,它运行良好,没有崩溃……啊,添加代码后问题非常明显。您创建了(保留)日期对象,然后在rangeForUnit中用自动删除的版本覆盖它们,然后发布自动删除的版本(顺便说一句,保留原始日期对象泄漏)。是不是&in[calendar RangeoUnit:unit startDate:&*startDate
错误?RangeoUnit不修改startDate.@ott该&*
最终是一个无操作,可以删除。您出色的解释使我更进一步了解Obj-C内存管理。非常感谢!!
- (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;
}
- (NSUInteger)retrieveSmokesForUnit:(NSCalendarUnit)unit
{
NSDate *beginDate;
NSDate *endDate;
[self rangeForUnit:unit containingDate:[NSDate date] startsAt:&beginDate andEndsAt:&endDate];
NSInteger count = [self numberOfSmokes:beginDate toDate:endDate];
return count;
}