我有一個應用程式需要存盤與引數的 SwiftUI 控制元件配置相關的資料(例如滑塊上限和下限、步長等)。引數型別可以是 Int 或 Double ,因此將這些資訊封裝在這樣的結構中是有意義的:
struct ParameterProfile<T: Comparable & SignedNumeric> {
var parameterName: String
var bounds: ClosedRange<T>
var units: String
var controlStep: T
}
我想讓這些組態檔可定制,并且由于用戶可能在多個設備上擁有該應用程式,我想將其存盤在 Core Data 中以便允許通過 CloudKit 進行同步。
此時的選項似乎是將上述轉換為 NSManagedObject 或使用 NSManagedObject 提供資料以實體化結構。
在第一種情況下,使用 NSManagedObject 并在存盤到 Core Data 之前序列化整個類似乎是使用 Codable 的最實用的方法,因此生成的物件將如下所示:
Class ParameterProfile<T: Comparable & SignedNumeric & Codable>: Codable, NSManagedObject {
var name: String
var bounds: ClosedRange<T>
var units: String
var controlStep: T
enum CodingKeys: String, CodingKey {
// haven’t figured out this bit yet!
}
}
然而,即使我添加了一個型別約束來指示泛型型別(無論它是什么)必須是可編碼的,但泛型型別不能在 Core Data 中表示。
就目前情況而言,看起來我必須創建一個 NSManagedObject 來有效地包裝一個結構,該結構具有表示有效范圍型別的可選屬性,例如:
class ProfileWrapper: NSManagedObject {
@NSManaged var name: String
// ...
@NSManaged var type: String
@NSManaged var lowerBound: Double
@NSManaged var upperBound: Double
var materialiseProfile: ParameterProfile {
ParameterProfile(name: name, type: type, lowerBound: lowerBound, upperBound: upperBound)
}
struct ParameterProfile {
var name: String
var intRange: ClosedRange<Int>?
var doubleRange: ClosedRange<Double>?
init(name: String, type: String, lowerBound: Double, upperBound: Double) {
self.name = name
switch type {
case "int":
intRange = Int(lowerBound)...Int(upperBound)
case "double":
doubleRange = lowerBound...upperBound
default:
fatalError("Undefined type")
}
}
}
}
上面的方法只是用于說明的粗略代碼,但它給了你一個想法——基本上它類似于在 Core Data 中存盤列舉的方式。存盤相對簡單的資料似乎有很多代碼,我必須單獨處理 SwiftUI 控制元件的型別。由于 ObjC 的限制,我懷疑這是必要的,但這是處理問題的最佳方法還是有其他策略
uj5u.com熱心網友回復:
一起使用泛型和核心資料并不容易,所以我認為在這種情況下,你只有兩個引數型別,Int 和 Double,最簡單的解決方案是為每個引數創建一個 NSManagedObject 子類。這不是最佳解決方案,但它非常簡單且易于使用。您當然需要復制您的獲取請求等,但另一方面,您不需要對正確的泛型型別進行任何復雜的轉換。
這是Double變體的外觀
class CDParameterProfileDouble: NSManagedObject {
@NSManaged var parameterName: String
@NSManaged var lowerBound: Double
@NSManaged var upperBound: Double
@NSManaged var units: String
@NSManaged var controlStep: Double
func toDomain() -> ParameterProfile<Double> {
ParameterProfile(parameterName: self.parameterName,
bounds: self.lowerBound...self.upperBound,
units: self.units,
controlStep: self.controlStep)
}
}
和同樣的 Int
class CDParameterProfileInt: NSManagedObject {
@NSManaged var parameterName: String
@NSManaged var lowerBound: Int
@NSManaged var upperBound: Int
@NSManaged var units: String
@NSManaged var controlStep: Int
func toDomain() -> ParameterProfile<Int> {
ParameterProfile(parameterName: self.parameterName,
bounds: self.lowerBound...self.upperBound,
units: self.units,
controlStep: self.controlStep)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/415122.html
標籤:
上一篇:如何在泛型類的具體類中參考型別
