CoreData并发和释放对象

时间:2016-07-12 08:56:29

标签: ios objective-c multithreading core-data concurrency

我目前正在验证我们在多线程环境中使用的新CoreData架构。为了分析我使用GDCoreDataConcurrencyDebugging打印警告,每次从错误的线程/队列访问ManagedObject时(据我所知)。

现在我收到了大量警告:

Invalid concurrent access to managed object calling 'release'

我能够在生成警告的地方设置一个断点,代码如下所示:

-(MyObject*) createMyObject {
    return (MyObject*)[self insertNewObjectEntityWithName:@"MyObject"];
}

-(NSManagedObject*) insertNewObjectEntityWithName:(NSString*) entityName {
    __block NSManagedObject *managedObject;
    [self.managedObjectContext performBlockAndWait:^(void) {
        managedObject = [NSEntityDescription insertNewObjectForEntityForName:entityName
                                      inManagedObjectContext:self.managedObjectContext];
    }];
    return managedObject;
}

它在返回后在createMyObject - 方法中断,我猜是在释放对象时。 CoreData-concurrency和object-release有什么特别之处吗? 我环顾四周,并没有提到有关物品释放的任何内容,只提到了我不使用的自动释放池。

2 个答案:

答案 0 :(得分:2)

您正在performBlockAndWait:来电执行工作,这是正确的。但是,您可以继续返回对象,可能来自不同的线程。那不合法。必须从创建它们的线程/队列访问所有托管对象,但objectID属性除外,该属性始终有效。

答案 1 :(得分:0)

plz使用此代码获取managedObjectContext。必须从创建它们的线程/队列访问管理对象。

 - (NSManagedObjectContext *)managedObjectContext
    {
        NSThread *thisThread = [NSThread currentThread];
        if (thisThread == [NSThread mainThread])
        {

            if (_managedObjectContext != nil) {
                return _managedObjectContext;
            }
            //
            if ([self persistentStoreCoordinator] != nil) {
                _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
                [_managedObjectContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
            }
            [_managedObjectContext setRetainsRegisteredObjects:YES];
            [_managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
            return _managedObjectContext;

        }
        else
        {
            //Return separate MOC for each new thread
            NSManagedObjectContext *threadManagedObjectContext = [[thisThread threadDictionary] objectForKey:@"MOC_KEY"];
            if (threadManagedObjectContext == nil)
            {
                threadManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
                NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
                [threadManagedObjectContext setPersistentStoreCoordinator: coordinator];
                [[thisThread threadDictionary] setObject:threadManagedObjectContext forKey:@"MOC_KEY"];

            }

            return threadManagedObjectContext;
        }
    }