使用枚举作为领域模型的属性
Posted
技术标签:
【中文标题】使用枚举作为领域模型的属性【英文标题】:Using enum as property of Realm model 【发布时间】:2015-05-21 07:22:37 【问题描述】:是否可以将枚举用作我的模型的属性?我目前有这样的课程:
class Checkin: RLMObject
dynamic var id: Int = 0
dynamic var kind: String = "checked_in"
var kindEnum: Kind = .CheckedIn
willSet self.kind = newValue.rawValue
enum Kind: String
case CheckedIn = "checked_in"
case EnRoute = "en_route"
case DroppedOff = "dropped_off"
....
它工作正常,但我希望能够将 kind
属性设为 Enum,并让 Realm 在将对象保存到商店时自动调用该属性上的 .rawValue
。这在 Realm 中是否可行,或者是否已经有功能请求?
【问题讨论】:
【参考方案1】:对于这种情况,您应该覆盖 kindEnum
的 setter 和 getter:
enum Kind: String
case CheckedIn
case EnRoute
case DroppedOff
class Checkin: Object
@objc dynamic var id = 0
var kind = Kind.CheckedIn.rawValue
var kindEnum: Kind
get
return Kind(rawValue: kind)!
set
kind = newValue.rawValue
【讨论】:
如果您可以将此示例添加到您的官方示例中,那就太好了。 这不是很好。你为什么不能这样做?:***.com/questions/26900302/…(Martin Krenek 的回答)? 您也可以直接将@objc
枚举与 Realm 一起使用,但这不适用于具有 String
关联值的 Swift 枚举。
在没有来自 Realm 的“官方”支持(如果可能的话)的情况下,这非常有用。谢谢。
您可以将 kind 变量设置为私有,因此您只能使用 kindEnum 更改其值。【参考方案2】:
我进一步完善了这个模型。
enum Thing: String
case Thing1
case Thing2
case Thing3
然后在我的 Realm 类对象中:
class myClass : Object
private dynamic var privateThing = Thing.Thing1.rawValue
var thing: Thing
get return Thing(rawValue: privateThing)!
set privateThing = newValue.rawValue
这让我们可以写
myClassInstance.thing = .Thing1
(将“Thing1”存储到 privateThing),但阻止输入
myClassInstance.privateThing = "Thing4"
这不是一个有效值,因此可以保持数据完整性。
【讨论】:
更新:我已经编辑了我的原始代码,因为 = "Thing1" 等是多余的,因为 Swift 对其 rawValue 使用与大小写等效的字符串文字,这更好,我们可以使用rawValue 设置更可靠和更清洁的默认值。 :-) 感谢您的补充,我真的很喜欢这个答案。 +1【参考方案3】:由于 Realm 支持 Objective-C 枚举并且它们可以由 Int
表示,你可以使用这个:
class Checkin: Object
dynamic var id: Int = 0
dynamic var kind: Kind = .checkedIn
@objc enum Kind: Int
case checkedIn
case enRoute
case droppedOff
....
如果您需要解析 String
或从 String
解析,您可以为 Kind
和 toString
函数使用自定义初始化程序。
GitHub有关于这个的讨论
这适用于 Swift 3.0
和 Realm 2.0.2
【讨论】:
如果你有一个Int
枚举很好的解决方案,但它看不到它如何与String
一起工作。 Kind
被转换为不支持自定义初始化程序或存储属性的 Objective-C 枚举.. ?
确实,除了Int
,我还没有找到适用于任何类型的解决方案
感谢您提供此信息。我更改了枚举以符合 int。如果您需要一个字符串值,您可以在枚举中创建自己的计算属性,并为不同的情况返回正确的值。
请注意,任何涉及 Int 枚举的迁移都需要分配原始值:obj["propertyName"] = Kind.checkedIn.rawValue【参考方案4】:
Diogo T 的解决方案在最近更新 RealmSwift 之前有效。最终,我们现在必须遵守 RealmEnum
协议才能成为 Realm Object
的托管属性。
@objc enum MyEnum: Int, RealmEnum
...
或者在下面的某个地方添加:
extension MyEnum: RealmEnum
RealmSwift documentation for it
【讨论】:
【参考方案5】:以RealmEnum
和RealmOptional
为例
@objc enum MyEnum: Int, RealmEnum
case first
case second
final class MyEntry: Object
//It should be let
let someVariable = RealmOptional<CRUD>()
//using
myEntry.someVariable.value = MyEnum.first
【讨论】:
【参考方案6】:避免强制展开的替代解决方案 得到返回东西(rawValue:privateThing)!
enum Kind: String, CaseIterable
case CheckedIn
case EnRoute
case DroppedOff
@objc dynamic var kindRaw = Kind.CheckedIn.rawValue
var kind: Kind
get
for kind in Kind.allCases where kindRaw == kind.rawValue
return kind
return .CheckedIn //default
set
kindRaw = newValue.rawValue
【讨论】:
【参考方案7】:Realm 10.0.0 引入了PersistableEnum
协议,无需任何第三方扩展即可轻松持久化枚举值。
enum TaskStatusEnum: String, PersistableEnum
case notStarted
case inProgress
case complete
// To use the enum:
class Task: Object
// Required enum property
@Persisted var status = TaskStatusEnum.notStarted
// Optional enum property
@Persisted var optionalTaskStatusEnumProperty: TaskStatusEnum?
【讨论】:
以上是关于使用枚举作为领域模型的属性的主要内容,如果未能解决你的问题,请参考以下文章