我有一个应用程序,我在启动时使用一系列操作下载数据,但由于未知的核心数据原因,它随机崩溃,所以我花了几天时间检查使用MagicalRecord更新/获取多线程核心数据的最佳实践。其中一个选项是启用多线程调试器-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都是一个局部变量,所以我对每个操作都有私有上下文,这样就不会中断主操作。关键是我为每个线程创建了一个私有上下文,我只是尝试使用这个上下文创建一个新的NSManagedObject实例,而Xcode说我违反了多线程核心数据规则。有谁知道发生了什么事吗?
发布于 2015-08-25 23:51:32
我们在开发自己的应用程序时也遇到了同样的问题。
当您尝试在与上下文线程不同的线程中执行写操作时,它有时会崩溃。
我们的解决方案是在AppDelegate.m文件上创建一个私有管理器。只需添加以下代码:
- (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:^{...}];https://stackoverflow.com/questions/32206967
复制相似问题