多线程违反核心数据

时间:2015-08-25 14:37:19

标签: ios multithreading core-data magicalrecord

我有一个应用程序,我在启动时使用操作列表下载数据,并且由于未知核心数据原因而随机崩溃,因此我花了几天时间检查使用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表示我违反了多线程核心数据规则。有没有人知道发生了什么?

0 个答案:

没有答案