主要目标:在第一个视图控制器中,我将点击单元格中的按钮 - >按钮调用entity.removeFrom“”(_ value:“”)方法 - >自动应从第二个视图控制器的表视图中删除相应的单元格。
发生什么:“”... entity.removeFrom“”(_ value:“”)方法 - >删除对象,设置为nil,但NSFetchedResultsController不删除相应的行。让tableview充满空单元格(来自剩余的nil对象)
问题:如何删除多对多关系中的多个对象并相应地更新NSFetchedResultsController。
关于应用使用swift 3我正在创建一个带标签栏控制器的基本待办事项列表应用。
第一个标签= tableView
ToDoItem
第二个标签= toDoItems
NSFetchedResultsController
核心数据实体:
FinishedCollection
,ToDoItem
FinishedCollection
与todoItems
有一对多关系(目的地为ToDoItem
)
操作顺序:
第一个标签
1)设置ToDoItem
属性isFinished
2)FinishedCollection.addToToDoItems(toDoItem)
或FinishedCollection.removeFromToDoItems(toDoItem)
3)自动更新第二个标签NSFetchedResultsController
问题:
当我removeFromToDoItems(toDoItem)
时,NSFetchedResults控制器中的属性被设置为nil,而不是完全删除对象(我不一定要完全删除对象)导致空单元格和百万亿个nil对象。如何在一对多关系中删除多个nil对象,并且只在NSFetchedResults控制器tableview选项卡中完成toDoItems
。
-
设置numberOfRowsInSection tableview方法时尝试过滤nil对象。在这种情况下似乎没有做任何事情
let notNilObjects = sectionInfo.objects.flatMap { 0 }
TableViewDataSource方法
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sections = fetchedResultsController?.sections
let sectionInfo = sections?[section]
return sectionInfo?.numberOfObjects ?? 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell( withIdentifier: "JournalCell", for: indexPath )
configure(cell, atIndexPath: indexPath)
return cell
}
// NSFetchedResultsDelegate方法
fileprivate func configure(_ cell: UITableViewCell, atIndexPath indexPath: IndexPath) {
guard let selectedObject = fetchedResultsController?.object(at: indexPath) else {
fatalError("Unexpected Object in FetchedResultsController")
}
let toDoItems = selectedObject.dayTasks?.allObjects as! [ToDoItem]
let toDo = ToDoItems.last
print(toDo?.name)
}
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
}
func controller(_ controller : NSFetchedResultsController<NSFetchRequestResult>,
didChange sectionInfo : NSFetchedResultsSectionInfo,
atSectionIndex sectionIndex: Int,
for type : NSFetchedResultsChangeType) {
switch type {
case .insert:
tableView.insertSections(NSIndexSet(index: sectionIndex) as IndexSet, with: .fade)
case .delete:
tableView.deleteSections(NSIndexSet(index: sectionIndex) as IndexSet, with: .fade)
case .move:
break
case .update:
tableView.reloadData()
}
}
func controller(_ controller : NSFetchedResultsController<NSFetchRequestResult>,
didChange anObject: Any,
at indexPath : IndexPath?,
for type : NSFetchedResultsChangeType,
newIndexPath : IndexPath?) {
switch type {
case .insert:
tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
tableView.deleteRows(at: [indexPath!], with: .fade)
case .update:
configure(tableView.cellForRow(at: indexPath!)!, atIndexPath: indexPath!)
case .move:
tableView.moveRow(at: indexPath!, to: newIndexPath!)
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
}
func initializeFetchedResultsController() {
let request: NSFetchRequest = ToDoItem.fetchRequest()
request.sortDescriptors = [ NSSortDescriptor( key: "timestamp", ascending: true ),
NSSortDescriptor( key: "isAccomplished", ascending: true) ]
fetchedResultsController = NSFetchedResultsController( fetchRequest : request,
managedObjectContext: CoreDataHelper.context,
sectionNameKeyPath : nil,
cacheName : nil )
fetchedResultsController?.delegate = self
do {
try fetchedResultsController?.performFetch()
}
catch {
print("Couldn't fetch results controller")
}
}
答案 0 :(得分:1)
在initializeFetchedResultsController
方法中添加
request.predicate = NSPredicate(format: "isFinished = 1")
答案 1 :(得分:0)
为了过滤从fetchedResultsController获取的NSSet,必须使用NSPredicate并将其分配给NSFetchRequest的request.predicate
属性
示例强>
let request = Entity.fetchRequest()
request.predicate = NSPredicate(format: "isAccomplished == YES")