行的CoreData更新导致插入空行

时间:2017-05-12 14:46:25

标签: ios swift core-data swift3

我正在学习如何使用CoreData并面对下面的问题。

我创建了这个函数,它应该更新现有行或插入新行。但是当我尝试更新现有版本时,app会插入空行。

以下是我的代码部分:

func saveSettingToDatabase()
{
    guard settingNameLabel.text != nil else {return}

    let context = AppDelegate.viewContext
    let tableContext = SettingsTable(context: context)

    // Get record if already exists
    let request: NSFetchRequest<SettingsTable> = SettingsTable.fetchRequest()
    let searchString = settingNameLabel.text!
    request.predicate = NSPredicate(format: "settingName = %@", searchString)
    let fetchResult = try? context.fetch(request)

    //If record exists, update it. Else - insert.
    if fetchResult?.count == 1 {
        let change = fetchResult?[0]
        change?.setValue(settingNameLabel.text, forKey: "settingName")
        change?.setValue(settingValueLabel.text, forKey: "settingValue")
        change?.setValue(booleanValueSwich.isOn, forKey: "booleanValue")
        try? context.save()
    } else
    {
        tableContext.settingName = settingNameLabel.text
        tableContext.settingValue = settingValueLabel.text
        tableContext.booleanValue = booleanValueSwich.isOn
        context.insert(tableContext)
        try? context.save()
    }
}

一步一步:

  1. 打开应用

  2. 使用test1填充settingNameLabel。

  3. 点击“获取”按钮。

  4. 值出现在各个文本字段中。以下是更新前数据库的屏幕截图:

  5. before update

    1. 将settingValueLabel.text中的值更改为test999。

    2. 点击保存。

    3. 如下图所示 - 价值已更改,但应用已添加空行(第1行)。

    4. after update

      我在这里放了断点:

      context.insert(tableContext)
      

      但是我的节目从未到过这里。并且没有其他插入可以在我的课程中完成。

      有人可以提出建议吗?

1 个答案:

答案 0 :(得分:1)

我发现此建议非常有用:Swift Core Data adding extra empty row 所以我在SettingsTable类中实现了awakeFromInsert函数。调试后,我可以看到插入是在这里初始化的:

let tableContext = SettingsTable(context: context)

我已将此行移至else语句中,现在它正常运行。

func saveSettingToDatabase()
{
    guard settingNameLabel.text != nil else {return}

    let context = AppDelegate.viewContext

    // Get record if already exists
    let request: NSFetchRequest<SettingsTable> = SettingsTable.fetchRequest()
    let searchString = settingNameLabel.text!
    request.predicate = NSPredicate(format: "settingName = %@", searchString)
    let fetchResult = try? context.fetch(request)

    //If record exists, update it. Else - insert.
    if fetchResult?.count == 1 {
        let change = fetchResult?[0]
        change?.setValue(settingNameLabel.text, forKey: "settingName")
        change?.setValue(settingValueLabel.text, forKey: "settingValue")
        change?.setValue(booleanValueSwich.isOn, forKey: "booleanValue")
        try? context.save()
    } else
    {
        let tableContext = SettingsTable(context: context)
        tableContext.settingName = settingNameLabel.text
        tableContext.settingValue = settingValueLabel.text
        tableContext.booleanValue = booleanValueSwich.isOn
        context.insert(tableContext)
        try? context.save()
    }
}

经过一些重构后,这个功能看起来更加清晰:

func saveSettingToDatabase()
{
    let context = AppDelegate.viewContext
    // Get record if already exists
    let request: NSFetchRequest<SettingsTable> = SettingsTable.fetchRequest()
    request.predicate = NSPredicate(format: "settingName = %@", settingNameTextField.text!)
    let fetchResult = try? context.fetch(request)

    //If record exists, update it. Else - insert.
    if fetchResult?.count == 1 {
        let change = fetchResult?[0]
        change?.settingName = settingNameTextField.text
        change?.settingValue = settingValueTextField.text
        change?.settingBooleanValue = settingBooleanValueSwitch.isOn
        try? context.save()
    } else
    {
        let addRecord = SettingsTable(context: context)
        addRecord.settingName = settingNameTextField.text
        addRecord.settingValue = settingValueTextField.text
        addRecord.settingBooleanValue = settingBooleanValueSwitch.isOn
        context.insert(addRecord)
        try? context.save()
    }
}