2016-03-15 32 views
0

我正在寻找一种有效的方法来比较NSManagedObject数组和我从文件中读取的基本相同的对象/结构数组,即文件“Item”具有与CoreData“Item”相同的属性。这是场景。我有一套我从标签分隔文件中读取的项目。在游戏的第一个版本中,我将这些项目存储到名为“Item”的核心数据实体中。将NSManagedObject数组与另一个“对象”类型的数组进行比较Swift 2

CoreData entity relationship

然后在比赛的第2版,我可以在平面文件中添加新的项目到平面文件或更新现有项目。我将在CoreData和文件数据之间使用的密钥是itemId。当我发布游戏的版本2时,我将版本1的NSManagedObject项目数据读取到数组中。我需要比较NSManagedObject数组和版本2文件项目数据。我可以遍历文件数据并为每个数组中的位置保留一个计数器,根据itemId匹配或不匹配将其递增。如果匹配,我想用==来比较数据,因为所有的属性都是相同的,但是对象是不同的。我不想将文件数据对象存储为临时或虚拟的NSManagedObject。如果我这样做,那么如果项目已经存在或者项目需要更新,那么我需要删除这个临时对象。

我只处理100个项目,所以从性能角度来看也许没有关系。创建NSManagedObjects用于比较目的并删除它们似乎效率低下,反过来将NSManagedObject转换为“文件项”对象或结构似乎也是低效的。

所以,这个问题的简短版本是,我如何有效地使用Swift 2比较NSManagedObject数组和另一个“Object”类型的数组?

回答

0

做了一些额外的研究。我发现下面的链接: How to implement the new Core Data model builder 'unique' property in iOS 9.0 Beta

1)我加了一个mergePolicy我managedObjectContext定义,4号线后评论:

lazy var managedObjectContext: NSManagedObjectContext = { 
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail. 
    let coordinator = self.persistentStoreCoordinator 
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) 
    managedObjectContext.persistentStoreCoordinator = coordinator 
    managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy 
    return managedObjectContext 
}() 

2),以及立即插入后保存managedObjectContext对象,我可以合并数据集。

if let contentLineArray = arrayFromContentsOfFileWithName("Item") { 
     // Loop through each item in the item file. Add each item and save. 
     // Using managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy 
     for lineArray in contentLineArray { 
      // skip the header line 
      if lineArray == contentLineArray[0] { 
       continue 
      } 

      // get the individual attributes from the line 
      let lineAttributeArray = lineArray.componentsSeparatedByString("\t") 

      let itemEntity = NSEntityDescription.entityForName(kItem as String, inManagedObjectContext:managedObjectContext) 
      let fileItem = NSManagedObject(entity: itemEntity!, insertIntoManagedObjectContext: managedObjectContext) as! Item 

      // set the properties of the managed object from the file object 
      fileItem.itemId = Int(lineAttributeArray[0]) // unique key 
      fileItem.slot = lineAttributeArray[1] 
      fileItem.itemType = lineAttributeArray[2] 
      fileItem.itemName = lineAttributeArray[3] 
      fileItem.imageName = lineAttributeArray[4] 
      fileItem.level = Int(lineAttributeArray[5])! 
      fileItem.rarity = lineAttributeArray[6] 
      fileItem.strength = Int(lineAttributeArray[7])! 
     } 

     // conflicts are managed at the time of save 
     saveManagedContext() 

     // used for unit testing and validating 
//   let nameSpaceClassName = NSStringFromClass(Item) 
//   let className = nameSpaceClassName.componentsSeparatedByString(".").last! as String 
//   let sortItemId = NSSortDescriptor(key: "itemId", ascending: true, selector: "localizedStandardCompare:") 
//   let itemArray = CoreDataHelper.fetchEntities(className, managedObjectContext: managedObjectContext, predicate: nil, sortDescriptors: [sortItemId]) as! [Item] 
//   print(itemArray) 

    } 

func saveManagedContext() { 
    if self.managedObjectContext.hasChanges { 
     do { 
      try self.managedObjectContext.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() 
     } 

     #if DEBUG 
      print("Managed context saved") 
     #endif 
    } 
} 

从本质上讲,如果我添加“的itemId”作为唯一的密钥或“约束”到我的项目CoreData实体,CoreData允许我执行UPSERT。 UP日期记录密钥是否存在或在SERT记录密钥是否不存在。此链接还显示如何为CoreData实体设置唯一约束。

Core Data Framework Reference -> NSMergePolicy Class Reference

相关问题