繁体   English   中英

从GCD后台队列添加到UIManagedDocument?

[英]Adding to UIManagedDocument from GCD background queue?

我正在从后台队列创建并向Core Data添加大量托管对象。 我的理解是我无法从后台线程访问上下文,所以我使用performBlock来安排将Core Data添加回创建上下文的同一队列。 这很好用......

我的问题是在测试期间我注意到通过删除[moc performBlock:^{ ... }]; 应用程序仍然按预期执行(可能甚至更快一秒)我需要performBlock吗? 我会假设我这样做并且正在以非线程安全的方式工作(现在:),我只是想检查以确保我的理解没有缺陷。

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(backgroundQueue, ^{ 
    // GET DATA
    // PROCESS DATA
    NSManagedObjectContext *context = [[self managedDocument] managedObjectContext];
    [moc performBlock:^{
          // ADD TO CORE DATA
          [Core createRodInContext:context withDictionary:fuelRodDictionary];
     }];

});

编辑:为createRodInContext添加了实现...

+ (Rod *)createRodInContext:(NSManagedObjectContext *)context withDictionary:(NSDictionary *)dictionary {

    // CREATE
    Rod *rod = [NSEntityDescription insertNewObjectForEntityForName:@"Rod" inManagedObjectContext:context];

    // POPULATE
    [neo setDataCode:[dictionary objectForKey:@"dataCode"]];
    [neo setDataName:[dictionary objectForKey:@"dataName"]];
    [neo setDataReference:[dictionary objectForKey:@"dataReference"]];
    ...
    return rod;
}

在后台线程中,您必须使用 [moc performBlock:^{ ... }]在主要托管对象上下文中插入(并填充)托管对象。

省略performBlock意味着您也在另一个线程(与后台队列关联)中使用托管对象上下文(在主线程上创建)。

这可能是偶然的 ,但是一旦主线程在与后台线程相同的时刻访问MOC,结果就是不可预测的,因为(正如您已经说过的),MOC不是线程安全的。

另请参阅适用 于OS X v10.7和iOS 5.0Core Data发行说明中的托管对象上下文的并发支持

限制(NSConfinementConcurrencyType)。

这是默认值。 您保证除了您创建它之外的任何线程都不会使用上下文。

但是对于其他并发类型(专用队列,主队列),除非您的代码已经在与MOC关联的队列上执行,否则您总是必须使用performBlock (或performBlockAndWait )。

暂无
暂无

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

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