在 iOS 的 CoreData 中同时插入

Posted

技术标签:

【中文标题】在 iOS 的 CoreData 中同时插入【英文标题】:Simultaneous inserts in CoreData in iOS 【发布时间】:2016-04-27 11:33:47 【问题描述】:

假设如果我有一千条来自 Web 服务 API 的记录,并且我想将这些记录添加到 privateContext 的核心数据中。我怎样才能同时而不是线性地做到这一点。

我可以应用dispatch_apply 之类的东西并运行

let entity:NSEntityDescription =  NSEntityDescription.entityForName(entityName,
            inManagedObjectContext:managedContext)!
let managedObject:NSManagedObject = NSManagedObject(entity: entity,
            insertIntoManagedObjectContext: managedContext)

同时?

【问题讨论】:

可以使用 dispatch_async、performBlock(在 managedContext 中)。但是不要每次都保存上下文,一旦你完成了所有的插入操作,就保存上下文。 我的问题有点不同....我想做同时插入。例如,我想在 10 个不同的队列中并行插入 100 条记录。 从这篇文章 (developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…) 看来,每个队列都需要不同的私有队列上下文。如果你让它工作,我想知道底层数据库是否允许并行更新或自行序列化它们。 @PhillipMills 是的,这就是我想知道的。我想知道进行这种优化是否有任何优势 您可能需要对其进行测试以了解或调查 SQLite(如果这是您的商店类型)如何响应线程。我不认为可以在 CoreData 级别做出任何保证,因为不同的存储会采取不同的方式。 (我什至可以想象一种数据库产品的行为会因架构而异。) 【参考方案1】:

试试这个:

func persistAsyncInContext<T:AnyObject>(parentContext:NSManagedObjectContext , objetcsFromJSON:[T] , completion:()->Void)

    let workQ = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT)
    let workGroup = dispatch_group_create()

    for objectFromJSON in objetcsFromJSON

        dispatch_group_enter(workGroup)
        let workerChildMoc = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
        workerChildMoc.parentContext = parentContext
        workerChildMoc.performBlock

            let managedObject = NSEntityDescription.insertNewObjectForEntityForName("entityName", inManagedObjectContext: workerChildMoc)
            //if objectFromJSON is also an array then loop it and move the line above that creates new object into the loop.

            do
            
                try workerChildMoc.save()
            
            catch
            
                //Handle error
            
            defer
                dispatch_group_leave(workGroup)
            
        
    

    dispatch_group_notify(workGroup, dispatch_get_main_queue())  () -> Void in
        do
            try parentContext.save()
        
        catch
        
            //Handle error
        
        //End of persist
        completion()
    

这会在子上下文中创建每个对象并保存它们,但考虑到对很多对象执行此操作效率不高,您可能希望创建 JSON 对象的二维数组(例如,如果您有 1000 个对象然后将它们分块为 10 个包含 100 个对象的数组,并在 10 个子上下文上异步解析 10 个数组。

希望对你有帮助。

【讨论】:

以上是关于在 iOS 的 CoreData 中同时插入的主要内容,如果未能解决你的问题,请参考以下文章

IOS中CoreData浅析

iOS 9 和 iOS 10 CoreData 同时

使用 CoreData 以编程方式创建实体/表,并在 Swift 3 for iOS 中将值插入该实体

NSFetchedResultsController + UICollectionViewDiffableDataSource + CoreData - 如何区分整个对象?

核心数据:如何在两个 NSManagedObjectContext 之间合并插入/更新/删除,同时将合并保持为可撤消的步骤?

IOS Coredata UNIQUE 约束失败: