我正在寻找一种有效的方法来比较NSManagedObject数组和我从文件中读取的基本相同的对象/结构数组,即文件“Item”具有与CoreData“Item”相同的属性。这是场景。我有一组项目,我从制表符分隔文件中读取。在游戏的第一个版本中,我将这些项目存储到名为“Item”的核心数据实体中。
然后在游戏的第2版中,我可以向平面文件添加新项目或更新平面文件中的现有项目。我将在CoreData和文件数据之间使用的键是itemId。当我发布游戏的第2版时,我将版本1 NSManagedObject Item数据提取到数组中。我需要将NSManagedObject数组与版本2文件Item数据进行比较。我可以遍历文件数据并为每个数组中的位置保留一个计数器,根据itemId匹配或不匹配来根据需要递增它们。如果匹配,我想使用==来比较数据,因为所有属性都相同,但对象是不同的。我不想将文件数据对象存储为临时或虚拟NSManagedObject。如果我这样做,那么如果项目已经存在或项目需要更新,我将需要删除此临时对象。
我只处理100件物品,所以从性能角度来看也许并不重要。创建NSManagedObjects以进行比较并删除它们似乎效率低下,相反,将NSManagedObject转换为“文件项”对象或结构似乎效率低下。
所以,问题的简短版本是,如何使用Swift 2有效地将NSManagedObject数组与另一个“Object”类型的数组进行比较?
答案 0 :(得分:0)
做了一些额外的研究。我找到了以下链接: How to implement the new Core Data model builder 'unique' property in iOS 9.0 Beta
1)我在我的managedObjectContext定义中添加了 mergePolicy ,评论后的第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”作为唯一键或“Constraint”添加到我的Item CoreData实体,CoreData允许我执行UPSERT。 UP 如果密钥存在,则记录日期;如果密钥不存在,则 SERT 记录。此链接还显示如何为CoreData实体设置唯一约束。
Core Data Framework Reference -> NSMergePolicy Class Reference