如何使用 Core Data 更新数据?

Posted

技术标签:

【中文标题】如何使用 Core Data 更新数据?【英文标题】:How can I update data using Core Data? 【发布时间】:2018-02-15 10:59:36 【问题描述】:

我的问题是我可以轻松地添加和删除数据,但是当我尝试在 Tableview 中更新数据时确实选择了方法,当我更新最后一行时它工作正常,但是当我尝试更新任何其他行时它会设置低于行数据的值。如果有人对此有答案,请帮助我。

import UIKit
import CoreData

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource 

    @IBOutlet weak var tableView: UITableView!


    var people = [Person]()

    override func viewDidLoad() 
        super.viewDidLoad()
        let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()

        do 
            let people = try PersistenceServce.context.fetch(fetchRequest)
            self.people = people
            self.tableView.reloadData()
         catch 
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    
    @IBAction func onPlusTapped() 
        let alert = UIAlertController(title: "Add Person", message: nil, preferredStyle: .alert)
        alert.addTextField  (textField) in
            textField.placeholder = "Name"
        
        alert.addTextField  (textField) in
            textField.placeholder = "Age"
            textField.keyboardType = .numberPad
        
        let action = UIAlertAction(title: "Post", style: .default)  (_) in
            let name = alert.textFields!.first!.text!
            let age = alert.textFields!.last!.text!
            let person = Person(context: PersistenceServce.context)
            person.name = name
            person.age = Int16(age)!
            PersistenceServce.saveContext()
            self.people.append(person)
            self.tableView.reloadData()
        
        alert.addAction(action)
        present(alert, animated: true, completion: nil)
    

    func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return people.count

    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
        cell.textLabel?.text = people[indexPath.row].name
        cell.detailTextLabel?.text = String(people[indexPath.row].age)
        return cell

    
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
        return true
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
        let person = people[indexPath.row]
        if editingStyle == .delete  
            PersistenceServce.context.delete(person)
            PersistenceServce.saveContext()
            people.remove(at: indexPath.row)
            self.tableView.deleteRows(at: [indexPath], with: .automatic)
        
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        let alert = UIAlertController(title: "Update Person", message: nil, preferredStyle: .alert)
        alert.addTextField  (textField) in
            textField.text = self.people[indexPath.row].name
        
        alert.addTextField  (textField) in
            textField.text = String(self.people[indexPath.row].age)
            textField.keyboardType = .numberPad
        
        let action = UIAlertAction(title: "Update", style: .default)  (_) in

        let name = alert.textFields!.first!.text!
        let age = alert.textFields!.last!.text!
            print(self.people)


            PersistenceServce.context.delete(self.people[indexPath.row])
            print(self.people)

            let person = Person(context: PersistenceServce.context)
            person.name = name
            person.age = Int16(age)!
            self.people.append(person)
            self.people.remove(at: indexPath.row)

            print(self.people)
            self.tableView.reloadRows(at: [indexPath], with: .automatic)
            PersistenceServce.saveContext()

        
        alert.addAction(action)
        present(alert, animated: true, completion: nil)
    




【问题讨论】:

How do you update a CoreData entry that has already been saved in Swift?的可能重复 不,它不是重复的 【参考方案1】:

你做的太过分了,每次更改都不需要删除并插入一个新的 Person 对象。只需更新对象的属性,Core Data 会处理其余的,因为它已经管理了对象。

类似

let selectedPerson = self.people[indexPath.row]
selectedPerson.name = ...
selectedPerson.age = ...

然后你可能需要在表格视图上调用 reloadData()/reloadRows(...)

【讨论】:

以上是关于如何使用 Core Data 更新数据?的主要内容,如果未能解决你的问题,请参考以下文章

Swift:当 didSelectRowAtIndexPath 时如何更新 Core Data 中的数据?

用户更新软件后如何保存Core Data?

iPhone 和 Core Data:如何在更新之间保留用户输入的数据?

Core Data 未更新可转换属性

如何在 Core Data iOS Swift 中删除和更新结构类型数组?

在使用 NSFetchedResultsController 更新 UITableView 时将来自 Web 的数据保存到 Core Data