背景: 我有一个具有两个核心数据实体(资产和组)的应用程序,具有一对多关系(一个组包含许多资产)。 CollectionView 获取组项目并将它们用作部分,资产是各个单元格。当用户保存新条目时,会调用 didChangeContentWith 方法,但新资产项使用“临时 ID”。
问题/崩溃: UI 显示正常,但是当用户点击单元格时,应用程序崩溃,因为它找不到具有该 NSManagedObjectID 的对象。
代码:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
var newSnapshot = NSDiffableDataSourceSnapshot<String, NSManagedObjectID>()
if let sections = controller.sections {
// Iterate through the fetched sections (groups)
for sectionInfo in sections {
if let group = sectionInfo.objects?.first as? Group {
// Append the section (group name) to the snapshot
newSnapshot.appendSections([group.name!])
// Get the objects associated with this Group
if let assets = group.assets {
let assetIDs = assets.map{ $0.objectID }
for id in assetIDs {
print("<<<< ID temp: \(id.isTemporaryID)")
}
// Append the Asset objects as items within the section (group)
newSnapshot.appendItems(assetIDs, toSection: group.name)
}
}
}
}
// Apply the snapshot to the UICollectionViewDiffableDataSource
dataSource.apply(newSnapshot, animatingDifferences: true)
}
保存功能:
context.performAndWait { [unowned self] in
let _ = generateOrUpdateAsset(with: id, name: self.name, priority: self.priority, comments: self.comments, context: context)
// Here the temp id is used
do {
try context.save()
// Here the temp id is not used
} catch {
print("Failed to saving test data: \(error)")
}
}
获取功能:
func performCoreDataFetch(){
if let context = self.context {
let fetchRequest = Group.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: false)]
fetchRequest.relationshipKeyPathsForPrefetching = ["asset"]
let predicate = NSPredicate(format: "ANY assets != nil")
fetchRequest.predicate = predicate
fetchResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: context,
sectionNameKeyPath: "name",
cacheName: nil)
fetchResultsController.delegate = self
try! fetchResultsController.performFetch()
}
}
非常感谢您的帮助!
新插入的对象没有永久ID。当您保存上下文时,Core Data 将为您创建一个永久 ID,或者您可以使用
obtainPermanentIDs(for: )
获取一个。但是,这可能不是解决您的问题的最佳方法。
解决您问题的最佳方法是让快照为
<String, Asset>
(或者无论是什么类型,我在您的问题中看不到)而不是<String, NSManagedObjectID>
,那么您不需要重新获取来自数据库的内容或执行任何转换步骤。