英文:
Core Data cannot assign value of type optional to type entity
问题
在我的下面的代码中,每次按下按钮时,变量"number"都会增加10。我想要覆盖"number"为旧值,然后保存、获取并在视图上显示它。
不幸的是,在"func fetchStats()"中,我收到以下错误消息:
如何将可选类型分配给实体类型?
或者更容易说:如何覆盖现有的变量"number"为旧值,然后使用Core Data保存、获取它(到实体(Statsohs)和属性(value)),最后显示它?
import UIKit
import CoreData
class ViewController: UIViewController {
    var number: Double = 0
    //引用托管对象上下文
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    //用于Stats的数据
    var average: Statsohs?
    @IBOutlet weak var LabelStats: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        fetchStats()
    }
    @IBAction func ActionButton(_ sender: UIButton) {
        number = number + 10
        average = Statsohs(context: context)
        average?.value = number
        LabelStats.text = String(format: "%.2f", average!.value)
        //保存数据
        do {
            try context.save()
        } catch {
        }
    }
    func fetchStats() {
        //从CoreData中获取数据以在视图中显示
        do {
            let stats = try context.fetch(Statsohs.fetchRequest()) as? [Statsohs]
            average = stats?.first
        } catch {
        }
    }
}
我尝试了不同的average变量声明,例如:
average: [Statsohs]?
但然后在Action中我会得到相同的错误消息,即average = Statsohs(context: context),还会出现类型[Statsohs]没有成员value的错误。
希望以这种方式每次更新值时都能分配值给Statsohs,然后保存、获取和显示。
英文:
In my code below the variable number is increased by 10 every time when button is pressed. I want to overwrite number to the old one then save, fetch and display it on the View.
Unfortunately I get the following error message in  func fetchStats()
How can I assign a type of optional to a type entity?
Or easier to say: How can I overwrite the existing variable "number" with the old one, then save, fetch it with Core Data (to entity (Statsohs) with attribute (value)) and finally display it?
import UIKit
import CoreData
class ViewController: UIViewController {
    var number : Double = 0
    
    //Reference to Managed Object Context
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    
    //Data for the Stats
    var average : Statsohs?
    @IBOutlet weak var LabelStats: UILabel!
    //--------------------------------------------------------------------------------------
    override func viewDidLoad() {
        super.viewDidLoad()
        fetchStats()
        
    }
//--------------------------------------------------------------------------------------
    @IBAction func ActionButton(_ sender: UIButton) {
        number = number + 10
        
        average = Statsohs(context: context)
        average?.value = number
        LabelStats.text = String(format: "%.2f", average!.value)
        
        //Save the data
                do {
                    try context.save()
                            
                }
                    catch {
                            
                }
        
    }
//--------------------------------------------------------------------------------------
    func fetchStats() {
        
            //Fetch the data from CoreData to display in the View
            do {
                average = try context.fetch(Statsohs.fetchRequest())
                   //Cannot assign value of type '[Statsohs]' to type 'Statsohs'
            }
            catch {
                
            }
        }
    
}
I tried different declarations of average in the beginning, e.g.:
average : [Statsohs]?
But then I will get the same error message in Action at average = Statsohs(conext: context)
And also member of type '[Statsohs]' has no member 'value'
I hope its possible in that way to assign value to Statsohs, save, fetch, display every time the updated value.
答案1
得分: 0
fetch 总是返回一个记录数组(多个项目),即使只有一个。
要覆盖记录的属性,您必须获取记录,修改属性,然后保存回去。
在 fetchStats 中,获取数组中的第一个(单个)记录。将其分配给 average,将其 value 分配给 number。如果不存在,则创建一个,并将 value 分配为零。
func fetchStats() {
    // 从CoreData获取数据以在视图中显示
    do {
        if let found = try context.fetch(Statsohs.fetchRequest()).first {
            average = found
            number = found.value
        } else {
            average = Statsohs(context: context)
            average?.value = 0
            saveData()
        }
        displayData()
    } catch {
        print(error)
    }
}
在 actionButton 中,将 number 增加 10,将结果分配给 value,显示并保存数据。
@IBAction func actionButton(_ sender: UIButton) {
    number += 10.0
    average?.value = number
    saveData()
    displayData()
}
最后添加辅助方法 displayData 和 saveData。
func saveData() {
    do {
        try context.save()
    } catch {
        print(error)
    }
}
func displayData() {
    labelStats.text = String(format: "%.2f", number)
}
英文:
fetch returns always an array of records (multiple items) even if there is only one.
To overwrite an attribute of a record you have to fetch the record, modify the attribute and save it back.
In fetchStats fetch the (single) record which is the first in the array. Assign it to average and its value to number. If it doesn't exist create one and assign zero to value
func fetchStats() {
        //Fetch the data from CoreData to display in the View
     do {
        if let found = try context.fetch(Statsohs.fetchRequest()).first {
            average = found
            number = found.value
        } else {    
            average = Statsohs(context: context)
            average?.value = 0
            saveData()
        }
        displayData()
            
    } catch {
        print(error)
    }
}
In actionButton increment number by 10, assign the result to value, display and save the data
@IBAction func actionButton(_ sender: UIButton) {
    number += 10.0
    average?.value = number
    saveData()
    displayData()
}
Finally add the helper methods displayData and saveData
func saveData() {
	do {
        try context.save()       
    } catch {
        print(error)              
    }
}
func displayData() {
	labelStats.text = String(format: "%.2f", number)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论