multithreading违反核心数据

我有一个应用程序,我在启动时使用操作列表下载数据,并随机崩溃,因为未知的核心数据原因,所以我花了几天的时间检查最佳实践,以使用MagicalRecord更新/获取multithreading核心数据中的数据。 其中一个选项是启用multithreadingdebugging器-com.apple.CoreData.ConcurrencyDebug 1 ,其中Xcode在违反其规则之一时停止应用程序。 所以,Xcode停止我的应用程序在这一行[SyncRequestEntity MR_createEntityInContext:[self getPrivateContext]]

 + (MagicalRecordVersionNumber) version { return MagicalRecordVersionNumber2_3; } @implementation NSManagedObjectContext (MagicalRecord) + (NSManagedObjectContext *) MR_context { return [self MR_contextWithParent:[self MR_rootSavingContext]]; } + (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext { NSManagedObjectContext *context = [self MR_newPrivateQueueContext]; [context setParentContext:parentContext]; [context MR_obtainPermanentIDsBeforeSaving]; return context; } - (void) MR_obtainPermanentIDsBeforeSaving { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(MR_contextWillSave:) name:NSManagedObjectContextWillSaveNotification object:self]; } + (NSManagedObjectContext *) MR_newPrivateQueueContext { NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; MRLogInfo(@"Created new private queue context: %@", context); return context; } @end @implementation MyClass - (NSManagedObjectContext *) getPrivateContext { if (self.privateContext == nil) { self.privateContext = [NSManagedObjectContext MR_context]; } return self.privateContext; } - (SyncRequestEntity *) getSyncRequest { SyncRequestEntity *syncRequest = [SyncRequestEntity MR_findFirstByAttribute:@"key" withValue:self.itemKey inContext:[self getPrivateContext]]; // Checking if the entity was sync previously with the same filters. if (syncRequest == nil) { syncRequest = [SyncRequestEntity MR_createEntityInContext: [self getPrivateContext]]; } return syncRequest; } @end @implementation NSManagedObject (MagicalRecord) + (id) MR_createEntityInContext:(NSManagedObjectContext *)context { if ([self respondsToSelector:@selector(insertInManagedObjectContext:)] && context != nil) { id entity = [self performSelector:@selector(insertInManagedObjectContext:) withObject:context]; return entity; } else { NSEntityDescription *entity = nil; if (context == nil) { entity = [self MR_entityDescription]; } else { entity = [self MR_entityDescriptionInContext:context]; } if (entity == nil) { return nil; } return [[self alloc] initWithEntity:entity insertIntoManagedObjectContext:context]; } } @end 

privateContext是每个操作的局部variables,所以我有每个操作的私有上下文,以不中断主要的。 重点是我为每个线程创build一个私有上下文,我只是试图创build一个新的NSManagedObject实例使用这个上下文和Xcode说我违反了multithreading核心数据规则。 有没有人有任何线索发生了什么?

我们在开发自己的应用时遇到同样的问题。

当您尝试在与上下文不同的线程中执行写入操作时,有时会崩溃。

我们的解决scheme是在AppDelegate.m文件上创build一个私人pipe理器。 只需添加以下代码:

 - (NSManagedObjectContext *)getPrivateManagedObjectContext { if (self.managedObjectContext != nil) { return self.managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self getPersistentStoreCoordinator]; if (coordinator != nil) { self.managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [self.managedObjectContext setPersistentStoreCoordinator:coordinator]; } return self.managedObjectContext; } 

那么当你需要执行任何操作的时候,你应该使用这个方法来确保块在上下文的同一个线程上运行:

 [self.managedObjectContext performBlock:^{...}]; [self.managedObjectContext performBlockAndWait:^{...}];