在核心数据
创建一个计算的属性我的影片迷上了一个Storyboard GUI(Xcode中9和SWIFT 4)核心数据模型现在我想添加这是由两部分衍生的特性。我有一个名为Workout的实体,它的两个属性“rpe”和“seconds”被组合起来创建一个新属性“rpeTSS”。我在我的核心数据模型中声明了“repTSS”作为属性。我已将其设置为瞬态。在核心数据
我已经使用编辑菜单下的“让子类NSManagedObject ...”选项尝试,但,这似乎产生具有错误的文件。我尝试了生成的Workout类的子类,但无法弄清楚如何将它绑定到GUI中。
我再发的扩展,锻炼:
extension Workout{
public override func value(forKey key: String) -> Any? {
if key == "rpeTSS"{
return (100/49)*rpe*rpe*Double(seconds)/3600
}else{return super.value(forKey: key)}
}
}
我会说实话,这并不“感觉”的权利。无论如何它(种)的作品。我现在可以获得rpeTSS的正确价值,它显示在我的GUI中。但是,如果我对rpe和/或秒进行更改,GUI不会更新。
我猜上面的方法有点破解,从而绕过了各种消息,使GUI更新。
什么是核心数据中添加派生属性的正确方法是什么?我试图用这种方式来实现这一点,这意味着如果我添加任何东西到我的数据模型中,我不必重写派生属性的代码。
不知道这是你的意思,但是...
我有一个名为Person
实体类。这里是我的两个类:
人+ CoreDataProperties.swift:
extension Person {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Total> {
return NSFetchRequest<Person>(entityName: "Person")
}
@NSManaged public var name: String?
@NSManaged public var age: Int
}
人+ CoreDataClass.swift:
@objc(Person)
public class Total: NSManagedObject {
}
这些被Xcode中产生。然后在我的ViewController
时,我想使用这个类我使用:
var curPerson: Person?
let personEntity = NSEntityDescription.entity(forEntityName: "Person", in: Singleton.s.context)!
Singleton.s.people = try Singleton.s.context.fetch(Person.fetchRequest())
// find the current person
for p in Singleton.s.people {
if p.name == curName { // got it
curPerson = p
break
}
}
现在我有一个Person
对象来操作。为了使新对象我用:
let newPerson = Person(entity: personEntity, insertInto: Singleton.s.context)
,并确保我的变化都保存我用:
(UIApplication.shared.delegate as! AppDelegate).saveContext()
谢谢。那给了我一些想法。在我的情况下,我使用GUI和阵列控制器中的绑定来创建我的对象。所以目前我没有实例化我的实体的实例。我试图保持这种方式 –
啊,陷入困境。好吧,祝你好运! – CodeNinja
仍然不知道这是做正确的方式,但它按照要求解决问题。不过,如果有一种“正确”的方式来做我想做的事,我会感兴趣。
我设法得到它全部重写的setValue更新(:forKey)方法在我的分机:
extension Workout{
public override func value(forKey key: String) -> Any? {
if key == "rpeTSS"{
if rpeTSS == 0{
self.rpeTSS = (100/49)*rpe*rpe*Double(seconds)/3600
}
return rpeTSS
}
return super.value(forKey: key)
}
public override func setValue(_ value: Any?, forKey key: String) {
super.setValue(value, forKey: key)
if (key == "rpe") || (key == "seconds") {
self.rpeTSS = calculateRPETSS()
}
}
func calculateRPETSS() -> Double{
return (100/49)*rpe*rpe*Double(seconds)/3600
}
}
我想出了外观和感觉正确的最终解决方案。它需要覆盖keyPathsForValuesAffectingValue(forKey :),如下所示:
extension Workout{
@objc dynamic var rpeTSS: Double{
return (100/49)*rpe*rpe*Double(seconds)/3600
}
override public class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String>{
let keyPaths = super.keyPathsForValuesAffectingValue(forKey: key)
switch key {
case "rpeTSS":
return keyPaths.union(Set(["seconds","rpe"]))
default:
return keyPaths
}
}
您可以创建实体类的对象并在其中设置属性?然后,无论何时您更改rpe或秒,都会更新rpeTSS属性。 – CodeNinja
不确定你的意思。实体类是在XCode中自动生成的。我尝试了继承它,但遇到了两个问题 - 1.如何使ManagedObject成为我的子类的一个实例并绑定到GUI中的子类;和2.我不断收到错误,我的计算属性不符合关键值。 –