2015-08-25 91 views
1

我有一个应用程序,我在启动时使用操作列表下载数据,并且随机因未知核心数据原因崩溃,因此我花了几天的时间检查最佳实践,以更新/获取多线程内核中的数据数据与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我的应用程序是一个局部变量为每个操作,所以我有私人上下文的每一个操作,以不中断主之一。重点是我为每个线程创建一个私有上下文,我只是试图使用这个上下文创建一个新的实例,并且Xcode说我违反了多线程核心数据规则。有没有人对发生的事情有任何线索?

+0

什么码'MR_context'的?你有没有考虑到块可以在不同的线程上运行? –

+0

添加详情@ AminNegm-Awad。我在这里没有使用任何块。 – Maystro

+0

您正在使用哪个版本的MagicalRecord? – casademora

回答

0

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

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

我们的解决方案是在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:^{...}]; 
+0

为什么我需要使用performBlock?我已经在一个后台线程(NSOperation)我只想创建/获取/插入实体使用我为每个操作创建的privateContext,但它似乎违反了我迄今为止不了解的规则之一。 – Maystro

+0

此解决方案未使用MagicalRecord ... – casademora

+0

问题是如果您执行同时写入操作,它可能会崩溃。您只需使用一个私有上下文并在同一个上下文线程中执行每个操作。 –