0

我写了简单的计数器应用程序。它使用CoreData来存储数据。在模型中,我有一个名为“计数器”的实体,其属性为“值”(Int64)和“位置”(Int16)。第二个属性是tableView中的位置。用户可以添加,删除或增加计数器。我也使用NSFetchedResultsController来填充我的tableView。应用程序的作品,但是当我,例如,添加5个计数器,更改它们的值,删除第二个和第三个值,并添加一个新的,计数器将不会插入tableView的结尾(这里是视频https://youtu.be/XXyuEaobd3c)。我的代码有什么问题?NSFetchedResultsController添加错误indexPath中的项目

import UIKit 
import CoreData 

class TableViewController: UITableViewController, NSFetchedResultsControllerDelegate { 

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 

var frc: NSFetchedResultsController<Counter> = { 
    let fetchRequest: NSFetchRequest<Counter> = Counter.fetchRequest() 
    let sortDescriptor = NSSortDescriptor(key: "position", ascending: true) 
    fetchRequest.sortDescriptors = [sortDescriptor] 
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 
    let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) 
    do { 
     try frc.performFetch() 
    } catch { 
     print(error) 
    } 
    return frc 
}() 


@IBAction func addCounter(_ sender: UIBarButtonItem) { 
    let counter = Counter(context: context) 
    counter.value = 0 
    counter.position = Int16(frc.fetchedObjects!.count) 
    do { 
     try context.save() 
    } catch { 
     print(error) 
    } 

} 

@IBAction func longPressed(_ sender: UILongPressGestureRecognizer) { 
    if sender.state == UIGestureRecognizerState.began { 
     let touchPoint = sender.location(in: self.view) 
     if let indexPath = tableView.indexPathForRow(at: touchPoint) { 
      // your code here, get the row for the indexPath or do whatever you want 
      let counter = frc.object(at: indexPath) 
      counter.value = 0 

      do { 
       try context.save() 
      } catch { 
       print(error) 
      } 
     } 
    } 

} 


override func viewDidLoad() { 
    super.viewDidLoad() 

    frc.delegate = self 
} 


// MARK: - Table view data source 

override func numberOfSections(in tableView: UITableView) -> Int { 
    guard let sections = frc.sections?.count else {return 0} 
    return sections 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    guard let sections = frc.sections else {return 0} 
    return sections[section].numberOfObjects 
} 


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 
    let counter = frc.object(at: indexPath) 
    cell.textLabel!.text! = String(counter.value) 

    return cell 
} 

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    tableView.beginUpdates() 
} 

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch type { 
    case .insert: 
     guard let indexPath = newIndexPath else {return} 
     tableView.insertRows(at: [indexPath], with: .fade) 
    case .delete: 
     guard let indexPath = indexPath else {return} 
     tableView.deleteRows(at: [indexPath], with: .fade) 
    case .update: 
     guard let indexPath = indexPath else {return} 
     let cell = tableView.cellForRow(at: indexPath) 
     let counter = frc.object(at: indexPath) 
     cell?.textLabel?.text = String(counter.value) 
    default: 
     break 
    } 
} 

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    tableView.endUpdates() 
} 

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    let counter = frc.object(at: indexPath) 
    counter.value += Int64(1) 

    do {try context.save()} 
    catch {print(error)} 

    tableView.deselectRow(at: indexPath, animated: true) 
} 

    // Override to support editing the table view. 
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    if editingStyle == .delete { 
      let counter = frc.object(at: indexPath) 
      context.delete(counter) 

     do { 
      try context.save() 
     } catch { 
      print(error) 
     } 
    } 
} 

}

回答

-1

你加入在错误的方式的位置。 我们假设你有

A1,A2,A3,A4,A5

然后将其删除A2,A3之后

您有 A1,A4,A5

因此增加新的一个是B3,因为现在计数为3 A1,B3,A4,A5

添加另一行成为B4,因此它可以在A4之前或之后的任何位置。

此订单归因于排序上的位置。

你能解决这个问题,通过获得上次读取对象,并增加了位置,结果,那么将是:

A1,A4,A5,B6,B7

相关问题