2017-10-05 182 views
0

創建一個計算的屬性我的影片迷上了一個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更新。

什麼是核心數據中添加派生屬性的正確方法是什麼?我試圖用這種方式來實現這一點,這意味着如果我添加任何東西到我的數據模型中,我不必重寫派生屬性的代碼。

+0

您可以創建實體類的對象並在其中設置屬性?然後,無論何時您更改rpe或秒,都會更新rpeTSS屬性。 – CodeNinja

+0

不確定你的意思。實體類是在XCode中自動生成的。我嘗試了繼承它,但遇到了兩個問題 - 1.如何使ManagedObject成爲我的子類的一個實例並綁定到GUI中的子類;和2.我不斷收到錯誤,我的計算屬性不符合關鍵值。 –

回答

1

不知道這是你的意思,但是...

我有一個名爲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()

+0

謝謝。那給了我一些想法。在我的情況下,我使用GUI和陣列控制器中的綁定來創建我的對象。所以目前我沒有實例化我的實體的實例。我試圖保持這種方式 –

+0

啊,陷入困境。好吧,祝你好運! – CodeNinja

1

仍然不知道這是做正確的方式,但它按照要求解決問題。不過,如果有一種「正確」的方式來做我想做的事,我會感興趣。

我設法得到它全部重寫的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 
} 

}

0

我想出了外觀和感覺正確的最終解決方案。它需要覆蓋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 
     } 
}