iOS:Swift:Core Data:值不使用 Private ManagedObjectContext 存储

Posted

技术标签:

【中文标题】iOS:Swift:Core Data:值不使用 Private ManagedObjectContext 存储【英文标题】:iOS:Swift:CoreData: Values are not stored using PrivateManagedObjectContext 【发布时间】:2016-07-26 06:22:09 【问题描述】:

在我的应用程序中,我使用了一个类(比如 CoredataHandler.swift)来存储和检索对象。我关注了this tutorials。我使用了策略 2:父/子托管对象上下文。 但是对象不存储在核心数据中。我没有使用 NSOperation,而是使用了普通的类对象。

class CoreDataHandler: NSObject 

//static var sharedInstance:CoreDataHandler = CoreDataHandler()

var privateManagedObjectContext:NSManagedObjectContext?
var mainManagedObjectContext:NSManagedObjectContext?


 override init() 

    print("core data handler constructor called")
    super.init()

    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let privateManagedObjectContextlocal = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    privateManagedObjectContextlocal.parentContext = appDelegate.managedObjectContext

    self.privateManagedObjectContext = privateManagedObjectContextlocal

    self.mainManagedObjectContext = appDelegate.managedObjectContext

    let notificationCenter = NSNotificationCenter.defaultCenter()
    notificationCenter.addObserver(self, selector: #selector(CoreDataHandler.managedObjectContextDidSave(_:)), name: NSManagedObjectContextDidSaveNotification, object: privateManagedObjectContext)


private func insertData(entityName:String,dataDictionary:Dictionary<String, AnyObject?>)
    synced(self)  () -> () in

        //        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

        let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: self.privateManagedObjectContext!)

        let newPerson = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: self.privateManagedObjectContext!)

        for (myKey, myVal) in dataDictionary 

            if myVal is Int 

                if let result_number = myVal as? NSNumber
                
                    let result_string = "\(result_number)"
                    newPerson.setValue(result_string, forKey: myKey)

                


            else
                newPerson.setValue(myVal, forKey: myKey)

            

        

        //print("insertData",newPerson)

        do 
            if ((self.privateManagedObjectContext?.hasChanges) != nil)

                try self.privateManagedObjectContext!.save()
            



         catch 

            // Replace this implementation with code to handle the error appropriately.

            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

            let nserror = error as NSError

            NSLog("Unresolved error \(nserror), \(nserror.userInfo)")

            abort()

        
    


// MARK: - Insert

func insertOfferObjects(arrOffer : Array<FoodItem>?) 
    synced(self)  () -> () in


        //Step1: Adding Offer Items
        if let _ = arrOffer 
            var foodArr:Array<NSManagedObject> = Array()

            for foodObj : FoodItem in arrOffer! 

                let offerItemEntity = self.createFoodItemEntity(foodObj)
                foodArr.append(offerItemEntity)

            

            self.insertData("OfferCategory", dataDictionary: ["categoryTitle": "Offers", "foodItemArray": NSOrderedSet(array: foodArr)])

        
    

值不存储在核心数据中。请给我最好的方法。

已编辑:更新 :: 来自答案,需要在子上下文时保存父级 已保存

            self.privateManagedObjectContext?.performBlockAndWait( 

                if ((self.privateManagedObjectContext?.hasChanges) != nil)

                     do 

                        print("It has changes...............")

                        try self.privateManagedObjectContext!.save()

                        self.mainManagedObjectContext?.performBlock(
                            do 
                            try self.mainManagedObjectContext!.save()
                            catch

                            
                        )

                     catch 

                        // Replace this implementation with code to handle the error appropriately.

                        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                        let nserror = error as NSError

                        NSLog("Unresolved error \(nserror), \(nserror.userInfo)")

                        abort()

                    

                
            )

【问题讨论】:

【参考方案1】:

保存子上下文只会将这些更改推送到父上下文。除非您还保存父上下文(将更改推送到持久存储),否则您的更改将不会写入磁盘。

来自NSManagedObjectContext 类参考:

当您在上下文中保存更改时,更改只会“一次存储”提交。如果您保存子上下文,则会将更改推送到其父上下文。在保存根上下文之前,更改不会保存到持久存储中。 (根托管对象上下文是其父上下文为 nil 的上下文。)

如果您不熟悉核心数据,我建议您不要担心并发和多个上下文,除非您确实有需要解决的问题。除非您要处理数千条记录,或者您有兴趣为可逆更改创建编辑上下文,否则单个主线程上下文将满足您的一切需求。

【讨论】:

感谢 jrturton,我正在调用多个 WebService API,并将这些响应存储在 CoreData 中。最初我没有使用任何子上下文对象。我用的是appDelegate.managedObjectContext。它工作正常,但有时应用程序会崩溃,说一些错误,如 referenceData64 ,无效参数错误。我google了一下,发现这个错误是由于并发问题而发生的。这就是我使用子上下文方法的原因,

以上是关于iOS:Swift:Core Data:值不使用 Private ManagedObjectContext 存储的主要内容,如果未能解决你的问题,请参考以下文章

IOS Swift Core Data如何在propertiesToFetch中添加不在propertiesToGroupBy中的字段

jQuery循环.each()JSON键/值不起作用

ClickHouse 日志显示未压缩文件的哈希值不匹配

OpenCV - 获取 Rtrees 值不起作用 - CopyTo 类型不匹配

熊猫选择列中的值不以字符串开头的行

vue为啥method值不改