开发者

Coredata - "NSObjectInaccessibleException - CoreData could not fulfill a fault"

I am new to Core data and still figuring out the nuts and bolts and this error has been bugging me for hours and I cant seem to find a solution. Any help is greatly appreciated.

The problem is like this

I have two views which fetch data from the server and Update the UI. I have set up the flow this way

view1 -> Send HTTP Req from Server - Receive Callback -> Save Data To Coredata -> Read From Core Data and display on the UI (callback and saving/reading Coredata happen in ViewController)

view2 -> Send HTTP Req from Server - Receive Callback -> Save Data To Coredata -> Read From Core Data and display on the UI (callback and saving/reading Coredata happen in ViewController)

View 2 repeats this process every 3 seconds as this is a auto refresh screen.

The problem is whenever I try to switch between views 1 and 2 real fast, it crashes the app with above error. If I wait for a few seconds on each view (wait for data to be fetched from the server), it works fine. Am I doing something wrong, what do I need to modify?

开发者_StackOverflow- (void) refreshData {
    [super refreshData];
    [[UserDataFactory sharedSingleton] refreshLoggedInUserDataAndRespondTo:self user:self.user];
}

- (BOOL) refreshDataCallback:(QExtendedHTTPOperation*)responseOperation {
    [self saveToCoreData: responseOperation.responseArray];
    NSMutableArray *tmp = [[NSMutableArray alloc] initWithArray:[self readFromCoreData]];
    [self setData: tmp];
    [tmp release];
    [self.tableView reloadData];
    return YES;
}

- (void) saveToCoreData:(NSArray *) responseArray{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    NSError *error;
    NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    [fetchRequest release];

    for (NSManagedObject *managedObject in items) {
            [self.managedObjectContext deleteObject:managedObject];
    }

    for (int i=0; i<[responseArray count]; i++) {
            CoreView1 *coreView1_ = [NSEntityDescription insertNewObjectForEntityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
            coreView_.id = [[responseArray objectAtIndex:i] id];    
            [self.managedObjectContext insertObject:coreView1_];
    }
    [self saveContext:self.managedObjectContext];
}

- (NSArray *) readFromCoreData{ 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    NSError *error;
    NSMutableArray *fetchedObjects = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
    [fetchRequest release];
    return [fetchedObjects autorelease];
}

This is the sample code I'm using, even View2 has the same callbacks and follows the same flow.

Edit 1 Forgot to mention this earlier, I always get the error in saveToCoreData method. Also, one more thing to note is that If I remove the code to delete objects it all works fine (I need to remove all the existing data from the table before I save the updated data). Not sure whats happening though.


The reason removing your delete code makes it work is because you are removing the data in the persistent store without updating the other view that still has managed object instances tied to that data still in memory. Remember, while Core Data deals with objects, each object has to have a row in the database behind it. When you delete that row, Core Data gets angry.

So, to fix this problem, and still delete your data, you should have your views listen for NSManagedObjectContextWillSaveNotification and/or NSManagedObjectContextDidSaveNotification notifications and update your views with the most up to date versions of data in your store. It is at this point you should throw away any Core Data objects your views are holding onto, and reload them from the store.


I just resolved this error in my code. Seems my cache was corrupted in some way. I used Christopher Pickslay & Keil Gillard's suggestion of deleting or renaming my cache, and voila, crash resolved. NSFetchedResultsController index beyond bounds


For info, yesterday, I had the same error. I checked in a live version of the app, and it was still there. yikes.

I ran through all the permutations of adding info to the core data stack until the crash occurred.

I then looked at the sqlite file from the app in the simulator library using SqliteManager. I found a data error in one table. This had occurred as there is a starter db used the first time the app was run. The error was in the starter db.

Ran the app again, testing each field in each table. Found several more occurrences. I remember reading this question, and thought maybe someone else could benefit from my mistake.


Your over releasing fetchedObjects in your readFromCoreData method. executeFetchRequest will return to you autoreleased objects anyway. When the current run loop finished executing (when you're jumping from views) then it attempt to release the objects twice (assuming you haven't used your own autorelease pools).

I'd change

return [fetchedObjects autorelease]; 

to

return fetchedObjects;
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜