简体   繁体   English

CoreData并发和释放对象

[英]CoreData concurrency and releasing objects

I'm currently validating our new CoreData architecture which is being used in a multi-threaded environment. 我目前正在验证新的CoreData体系结构,该体系结构已在多线程环境中使用。 For analyzing I'm using GDCoreDataConcurrencyDebugging which prints a warning, every time a ManagedObject is accessed from the wrong thread / queue (as far as I understood). 为了进行分析,我使用GDCoreDataConcurrencyDebugging打印警告,每次从错误的线程/队列访问ManagedObject时(据我所知)。

Now I'm getting tons of warnings like this: 现在我收到大量这样的警告:

Invalid concurrent access to managed object calling 'release'

I was able to put a break-point where the warning is generated and the code looks like this: 我能够在生成警告的地方放置一个断点,代码如下所示:

-(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;
}

Its breaking in the createMyObject -method after the return, which I guess is when the objects are being released. 返回之后,它打破了createMyObject方法,我猜这是对象被释放的时间。 Is there anything special I missed with CoreData-concurrency and object-release? 我在CoreData并发性和对象释放方面有什么特别的错过吗? I've looked around and there isn't anything being mentioned about object-release, only about autoreleasepools which I'm not using. 我环顾四周,没有提到任何有关对象释放的内容,仅涉及到我没有使用的自动释放池。

You are performing the work in a performBlockAndWait: call, which is correct. 您正在performBlockAndWait:调用中执行工作,这是正确的。 However, you proceed to return the object, presumably from a different thread. 但是,您可能继续从其他线程返回对象。 That is not legal. 那是不合法的。 All managed objects must be accessed from the thread/queue on which they are created, with the exception of the objectID property, which is always valid. 必须从创建对象的线程/队列访问所有托管对象,但objectID属性始终有效。

plz use this code to get managedObjectContext .managed objects must be accessed from the thread/queue on which they are created. 请使用此代码获取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;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM