Core data crash occurring since iOS 10

自闭症网瘾萝莉.ら 提交于 2019-12-04 14:49:25

If the majority of your code base is, as your suggest, asynchronous and you are trying to perform a synchronous save operation within this asynchronous block, there is every reason to suspect that is why you're receiving the NSPersistentStoreCoordinator error in the error message.

The key is the issue with the NSPersistentStoreCoordinator (PSC) failing to properly coordinate the data save. Unless I'm mistaken the error message identifies that the PSC is locked when you ask the PSC to respond to the call to save for that MOC.

In my humble opinion your problem still most likely stems from your call to performBlock... in this code you're performing a fetch request, then updating a property, then inserting the object back into the MOC, then saving, all in the same block. These are very different functions taking different amounts of processing power and time, all dumped into one single concurrency block.

Also, how you instantiate a property when using concurrency and blocks is important. You may need to check where in your code is most appropriate to instantiate your properties.

So some questions...

  1. Do you need every line of this code in a performBlock? Consider that, unless you're blocking your UI, the fetch request and the update to your property may be ok in code outside the call to performBlock.
  2. If you do need every line of this code in a core data concurrency block such as performBlock, have you considered instead embedding your call to save in a "block-within-a-block" and using performBlockAndWait?

The Apple developer website has an example of embedding a save call into a performBlockAndWait block, included (in part) following:

NSManagedObjectContext *moc = '…; //Our primary context on the main queue

NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[private setParentContext:moc];

[private performBlock:^{
    'Complete your fetch request and update the managed object's property.

    NSError *error = nil;
    if (![private save:&error]) {
        NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
        abort();
    }
    [moc performBlockAndWait:^{
        NSError *error = nil;
        if (![moc save:&error]) {
            NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
            abort();
        }
     }];
}];

If you're able to update your question with a little more code and a more detailed description I might be able to provide a more accurate fix for your specific problem.

Also I'd recommend you do some research...

Despite the age of the book, the concepts of concurrency are still very well explained in "Core Data, 2nd Edition, Data Storage and Management for iOS, OS X, and iCloud" (Jan 2013 from The Pragmatic Bookshelf) by Marcus S. Zarra, and in particular Chapter 4 titled "Performance Tuning” and Chapter 5 titled "Threading”.

Another valuable book on core data from Apress publishers – "Pro iOS Persistence Using Core Data", by Michael Privat and Robert Warner.

No longer occurs as of iOS 10.3. Root cause is still unknown. Assuming some iOS memory management break in 10.2, with a fix in 10.3.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!