在我們正常的項(xiàng)目中使用,簡(jiǎn)單的增刪改查,當(dāng)然可以實(shí)現(xiàn)大多數(shù)的功能休偶,但是有的實(shí)現(xiàn)的話(huà)相對(duì)可能復(fù)雜一些,比如保存的數(shù)據(jù)改變了我們要刷新tableview的數(shù)據(jù)暗挑。這里coredata中提供了一個(gè)NSFetchedResultsController類(lèi)來(lái)和tableview一起使用笋除,下面我們看一下如何使用NSFetchedResultsController和tableview
-
新建NSFetchedResultsController,并進(jìn)行初始化
這里需要提一下的是,sort排序是必須添加的炸裆,否則運(yùn)行后報(bào)錯(cuò)
var controller: NSFetchedResultsController<DemoModel>!
func initController() {
let request: NSFetchRequest<DemoModel> = DemoModel.fetchRequest()
//條件查詢(xún)
let predicate: NSPredicate = NSPredicate(format: "id == %@", "1")
request.predicate = predicate
//排序
let sort = NSSortDescriptor(key: "id", ascending: false)
request.sortDescriptors = [sort]
//sectionNameKeyPath為section的title對(duì)應(yīng)的key垃它,nil的話(huà)代表只有一個(gè)section
controller = NSFetchedResultsController(fetchRequest: request, managedObjectContext: CONTEXT, sectionNameKeyPath: "title", cacheName: nil)
controller.delegate = self
do {
try controller.performFetch()
}catch {
print("獲取數(shù)據(jù)失敗")
}
}
* ### 實(shí)現(xiàn)NSFetchedResultsControllerDelegate,當(dāng)coredata中的數(shù)據(jù)發(fā)生改變的時(shí)候調(diào)用
* ##### controllerDidChangeContent只使用這個(gè)方法烹看,當(dāng)數(shù)據(jù)改變完成后調(diào)用国拇,直接刷新tableview的數(shù)據(jù)
```swift
/// 當(dāng)coredata存儲(chǔ)的數(shù)據(jù)改變后調(diào)用的方法,這里直接更新tableview
///
/// - Parameter controller: <#controller description#>
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.reloadData()
}
-
當(dāng)然也可以添加一些刷新動(dòng)畫(huà),或者不需要等數(shù)據(jù)改變完成后才更新ui的設(shè)置
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.beginUpdates()
}
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: .left)
break
case .delete:
tableView.deleteRows(at: [indexPath!], with: .right)
break
case .update:
self.configureCell(cell: tableView.dequeueReusableCell(withIdentifier: identifier), indexPath: indexPath)
break
case .move:
tableView.deleteRows(at: [indexPath!], with: .none)
tableView.reloadSections([newIndexPath?.section], with: .none)
break
}
}
/// 當(dāng)coredata存儲(chǔ)的數(shù)據(jù)改變后調(diào)用的方法惯殊,這里直接更新tableview
///
/// - Parameter controller: <#controller description#>
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.endUpdates()()
}
-
實(shí)現(xiàn)UITableView的datasource,進(jìn)行數(shù)據(jù)綁定贝奇,這里只寫(xiě)出了和coredata相關(guān)的方法
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return self.controller.sections!.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.controller.sections![section].numberOfObjects
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.controller.sections![section].name
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//coreData的數(shù)據(jù)模型的獲取
let model = self.controller.object(at: indexPath)
...
}
}
上一節(jié):CoreData的使用(二)---增刪改查