dir*_*ill 7 multithreading core-data objective-c ios
我有一个随机的错误困扰了我几个月,我根本无法弄清楚.我会说它在1000次中失败的次数少于1次.我必须正确配置CoreData,但我无法弄清楚或重新创建它.基本要点是我从服务器接收一些信息,然后我在后台线程中更新CoreData对象.UI不会立即需要CoreData对象.
所有这些都在DataService中执行,它引用了最初在AppDelegate中创建的NSManagedObjectContext.注意:引用[DataService sharedService]的任何内容都使用AppDelegate.NSManagedObjectContext:
@interface DataService : NSObject {}
@property (nonatomic,strong) NSManagedObjectContext* managedObjectContext;
@end
Run Code Online (Sandbox Code Playgroud)
当服务器返回数据时,将调用updateProduct方法:
@implementation DataService
+ (NSManagedObjectContext*) newObjectContext
{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; //step 1
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[context setPersistentStoreCoordinator:appDelegate.persistentStoreCoordinator];
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[appDelegate.managedObjectContext observeContext:context];
return context;
}
+(void) saveContext:(NSManagedObjectContext*) context
{
NSError *error = nil;
if (context != nil) {
if ([context hasChanges] && ![context save:&error]) {
// Handle Error
}
}
}
+(void) updateProduct: (Product*) product
{
if(product == nil)
return;
//run in background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void){
//create private managed object
NSManagedObjectContext *context = [DataService newObjectContext];
CoreDataProduct* coreProduct = [DataService product:product.productId withObjectContext:context];
if(product != nil)
{
//copy data over from product
coreProduct.text = product.text;
//ERROR HAPPENS HERE on save changes
[DataService saveContext:context];
}
//remove background context listening from main thread
[DataService.managedObjectContext stopObservingContext:context];
});
}
@end
Run Code Online (Sandbox Code Playgroud)
我使用在GitHub上浮动的常规NSManagedObjectContext + Helper.h类别文件,并且在[DataService.managedObjectContext mergeChangesFromNotification:(NSNotification*)notification]方法中发生了我的EXC_BAD_ACCESS KERN_INVALID_ADDRESS错误
@implementation NSManagedObjectContext (Helper)
- (void) mergeChangesFromNotification:(NSNotification *)notification
{
//ERROR HAPPENS HERE
[self mergeChangesFromContextDidSaveNotification:notification];
}
@end
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚为什么mergeChangesFromContextDidSaveNotification方法随机失败.我认为错误是由于丢失了对原始共享managedObjectContext的引用.虽然如果这是真的,我想我会期望错误出现在updateProduct方法中,而不是在类别类中.
我想newObjectContext和stopObservingContext方法都引用了主线程中后台线程上的managedObjectContext.由于我正在创建一个私有的managedObjectContext,我是否甚至需要让主线程共享上下文知道私有上下文?如果是这样,我做错了吗?
在此先感谢您的帮助.
看来是因为新的 NSManagedObjectContext 是在后台线程上创建的,所以需要在主线程上观察原始/父 NSManagedObjectContext。一旦我将observeContext 更改为observeContextOnMainThread,这个CoreData 问题似乎就消失了。我希望这可以帮助别人。
这是我更新的方法:
+ (NSManagedObjectContext*) newObjectContext
{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; //step 1
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[context setPersistentStoreCoordinator:appDelegate.persistentStoreCoordinator];
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[appDelegate.managedObjectContext observeContextOnMainThread:context];
return context;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2420 次 |
| 最近记录: |