我有NSFetchedResultsController
从CoreData
获取对象并更新UICollectionView
以相应地显示数据。 UICollectionView
中的数据根据CoreData
关系中的属性按部分组织。这种关系如下所示
// an Item belongs to exactly one Category - a Category can host multiple Items
Item <<---> Category
我添加了一个新的Item
,其中Category
已经存在于数据库中,新的部分会添加到UICollectionView
,但这仅适用于第一个新的Item
- 稍后添加的每个新Item
都会插入此新部分。新部分未显示在sqlite
数据库中,只显示在由UICollectionView
管理的NSFetchedResultsController
中。
我使用以下代码插入新项目
let newItem = Item(context: managedObjectContext)
...
let request: NSFetchRequest<Category> = Category.fetchRequest()
request.predicate = NSPredicate(format: "name = %@", "categoryA")
do {
let searchResults = try managedObjectContext.fetch(request)
newItem.category = searchResults.first
} catch {
print("Error with request: \(error)")
}
关闭应用并重新启动它后,新版块会消失,所有Items
都位于正确的部分 - NSFetchedResultsController
可能有问题,所以这是重要的代码。< / p>
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
if type == NSFetchedResultsChangeType.insert {
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.insertSections(NSIndexSet(index: sectionIndex) as IndexSet)
}
})
)
}
else if type == NSFetchedResultsChangeType.update {
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.reloadSections(NSIndexSet(index: sectionIndex) as IndexSet)
}
})
)
}
else if type == NSFetchedResultsChangeType.delete {
blockOperations.append(
BlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.deleteSections(NSIndexSet(index: sectionIndex) as IndexSet)
}
})
)
}
}
以下是在UICollectionView
添加新Item
后CoreData
的图片
修改
我使用此代码实例化NSFetchedResultsController
var _fetchedResultsController: NSFetchedResultsController<Item>? = nil
var fetchedResultController: NSFetchedResultsController<Item> {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest: NSFetchRequest<Item> = Item.fetchRequest()
let managedObjectContext = CoreDataStack.sharedInstance.getContext()
fetchRequest.predicate = NSPredicate(format: "completed != true")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "category", ascending: true)]
let resultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath:"category", cacheName: nil)
resultsController.delegate = self;
_fetchedResultsController = resultsController
do {
try _fetchedResultsController!.performFetch()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror)")
}
return _fetchedResultsController!
}