我有2个标签应用程序。在第一个中,我正在创建“Sample”和“SampleList”实体的对象。每个sampleList包含一个ID和一组样本。每个样品都包含日期和温度属性。
在第二个标签中,我在tableView中显示我的数据。我实现了
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
方法以删除SampleLists。在我的xcdatamodel
中,SampleList和Sample之间关系的删除规则是Cascade
。
我的问题是,当我尝试删除刚刚创建的SampleList时,应用程序崩溃并收到EXC_BAD_ACCESS
信号。如果我重新启动它,那么我就可以毫无问题地删除“旧”sampleList。
之前,我遇到了以下问题:我无法显示自我启动应用程序后创建的sampleLists,因为它也崩溃了。我还收到了EXC_BAD_ACCESS
信号。实际上,似乎创建该集合的最后一个样本的日期是nil
。如果我没有发布用于设置样本日期的NSDate,我就不再有这个问题......
如果有人能帮助我找出可能导致我麻烦的事情,那就太棒了!
以下是我用来创建新实例的方法:
SampleList *newSampleList = (SampleList *)[NSEntityDescription insertNewObjectForEntityForName:@"SampleList" inManagedObjectContext:managedObjectContext];
[newSampleList setPatchID:patchID];
NSMutableSet *newSampleSet = [[NSMutableSet alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
for (int i = 0; i < [byteArray count]; i=i+4, sampleCount++) {
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:year];
[comps setMonth:month];
[comps setDay:day];
[comps setHour:hours];
[comps setMinute:minutes];
NSDate *sampleDate = [gregorian dateFromComponents:comps];
Sample *newSample = (Sample *)[NSEntityDescription insertNewObjectForEntityForName:@"Sample" inManagedObjectContext:managedObjectContext];
[newSample setSampleDate:sampleDate];
[newSample setSampleTemperature:[NSNumber numberWithInt:temperature]];
[newSampleSet addObject:newSample];
[comps release];
//[sampleDate release];
}
[newSampleList setSampleSet:newSampleSet];
// [newSampleSet release];
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"Could not Save the context !!");
}
[gregorian release];
编辑 我发现了自己的错误。 我正在为每个sampleDate做一个这样的比较:
NSDate *maxDate = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:0];
(...)
for (int i = 0; i < [byteArray count]; i=i+4, sampleCount++) {
(...)
if ([maxDate compare:sampleDate] == NSOrdredAscending){
max = sampleDate;
}
我本应该去做的地方:
if ([maxDate compare:sampleDate] == NSOrdredAscending){
[maxDate release];
maxDate = [sampleDate retain];
}
答案 0 :(得分:1)
根据NSEntityDescription的文档,
+ (id)insertNewObjectForEntityForName:(NSString *)entityName inManagedObjectContext:(NSManagedObjectContext *)context
返回一个自动释放的对象。所以你不需要在以下之后发布它:
[newSampleList setSampleSet:newSampleSet];
newSampleList最终将自动释放,这会导致您在重新启动应用时有时会获得EXC_BAD_ACCESS。
Apple的memory management documentation将为您提供最佳实践,帮助您自己何时释放对象以及何时自动释放对象。
答案 1 :(得分:0)
我喜欢使用以下方法来获取更具信息性的Core Data错误报告:
- (void) detailedStoreError:(NSError *)error {
NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
NSArray *_detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if (_detailedErrors != nil && [_detailedErrors count] > 0) {
for (NSError *_detailedError in _detailedErrors) {
NSLog(@" DetailedError: %@", [_detailedError userInfo]);
}
}
else {
NSLog(@" %@", [error userInfo]);
}
}
您可以按如下方式使用它:
NSError *error;
if (![managedObjectContext save:&error]) {
[self detailedStoreError:error];
}
更详细的错误报告可以帮助您进行故障排除。