开发者

CoreData : App crashes when deleting last instance created

I have a 2 tabs application. In the first one, I'm creating objects of the "Sample" and "SampleList" entities. Each sampleList contains an ID and a set of samples. Each sample contains a date and temperature property.

In the second tab, I'm displaying my data in a tableView. I implemented the

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

method in order to delete SampleLists. In my xcdatamodel the delete rule for my relationship between SampleList and Sample is Cascade.

My problem is that when I try to delete SampleList I just created, the app crashes and I receive a EXC_BAD_ACCESS signal. If I restart it, then I'm able to delete "old" sampleList without any problems.

Earlier, I had the following problem : I couldn't display the the sampleLists I created since I launched the app, because it crashed too. I received also the EXC_BAD_ACCESS signal. Actually, it seemed that the date of the last sample created of the set was nil. If I am not releasing the NSDate I'm using to set the sample's date, I don't have this problem anymore...

If anyone could help me to find out what could cause my troubles it would be great !!

Here is the method I'm using to create new instances :

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

edit : I found my mistake. I was doing a comparaison for each sampleDate like this:

NSDate *maxDate = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:0];
(...)
for (int i = 0; i < [byteArray count]; i=i+4, sampleCount++) {
    (...)
    if ([maxDate compare:sampleDate] == NSOrdredAscending){
        max = sampleDate;
    }

Where I should have been doing:

if ([maxDate compare:sampleDate] == NSOrdredAscending){
    [maxDate release];
    maxDate = [sampleDate retain];
}


According to the documentation for NSEntityDescription,

+ (id)insertNewObjectForEntityForName:(NSString *)entityName inManagedObjectContext:(NSManagedObjectContext *)context

returns an autoreleased object. So you don't need to release it after:

[newSampleList setSampleSet:newSampleSet];

newSampleList will be autoreleased eventually, which is causing what you see as sometimes getting a EXC_BAD_ACCESS when you restart your app.

Apple's memory management documentation will give you a best practices for when you need to release an object yourself and when objects are autoreleased.


I like to use a method like the following to get a more informative Core Data error report:

- (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]);
    }
}

You might use it as follows:

NSError *error;
if (![managedObjectContext save:&error]) {
    [self detailedStoreError:error];
}

A more informative error report may help you with troubleshooting.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜