【问题标题】:Swift: Storing states in CoreData with enumsSwift:使用枚举在 CoreData 中存储状态
【发布时间】:2015-01-10 02:12:28
【问题描述】:

我想在 CoreData 中存储托管对象的枚举状态

enum ObjStatus: Int16 {
    case State1 = 0
    case State2 = 1
    case State3 = 3
}

class StateFullManagedObject: NSManagedObject {
    @NSManaged var state: Int16
}

最后一步是将 StateFullManagedObject 的状态变量转换为 ObjStatus 以进行直接比较,这对我不起作用。例如,我不能在和 Int16 和 Int16 枚举之间使用 == 运算符。我得到的编译时错误是

Int16 不能转换为 'MirrorDisposition'

。请参阅下面的条件:

var obj: StateFullManagedObject = // get the object

if (obj.state == ObjStatus.State1) { // Int16 is not convertible to 'MirrorDisposition'

}

如何比较/分配 Int16 和枚举?

【问题讨论】:

    标签: core-data swift


    【解决方案1】:

    您可以使用ObjStatus 的.rawValue 属性提取原始Int16 值。

    // compare
    obj.state == ObjStatus.State1.rawValue
    
    // store
    obj.state = ObjStatus.State1.rawValue
    

    但您可能想为它实现stateEnum 访问器:

    class StateFullManagedObject: NSManagedObject {
        @NSManaged var state: Int16
        var stateEnum:ObjStatus {                    //  ↓ If self.state is invalid.
            get { return ObjStatus(rawValue: self.state) ?? .State1 }
            set { self.state = newValue.rawValue }
        }
    }
    
    // compare
    obj.stateEnum == .State1
    
    // store
    obj.stateEnum = .State1
    
    // switch
    switch obj.stateEnum {
    case .State1:
        //...
    case .State2:
        //...
    case .State3:
        //...
    }
    

    【讨论】:

    • 是的,这就是我所做的。我用“Raw”作为核心数据属性的后缀,然后有一个具有正确名称的计算属性来处理从枚举到原始 int 的转换。
    • 这是一个非常干净漂亮的快速解决方案!谢谢!!
    • 您应该肯定检查其他答案以获得真正的干净解决方案。
    • 但我想使用枚举中的关联值如何在核心数据中做到这一点
    【解决方案2】:

    您可以将您的枚举声明为@objc。然后这一切都会自动运行。这是我正在从事的一个项目的 sn-p。

    // Defined with @objc to allow it to be used with @NSManaged.
    @objc enum AgeType: Int32
    {
        case Age                = 0
        case LifeExpectancy     = 1
    }
    
    /// The age type, either Age or LifeExpectancy.
    @NSManaged var ageType: AgeType
    

    在 Core Data 模型中,ageType 设置为 Integer 32 类型。

    【讨论】:

    • 这是一个更简洁的实现。谢谢!
    • 绝对是最好的解决方案。无需私有复制字段、转换器等。
    • 我不认为它在最新的 swift 2 中工作 - 我收到此错误:属性无法标记 @NSManaged 因为它的类型无法在 Objective-C 中表示
    • @MobileBloke 该属性是否声明为可选?
    • 这个解决方案适用于 Xcode 8/Swift 3/iOS 10,我只需要创建枚举 public。
    【解决方案3】:

    Xcode 12.5 Swift 5

    我将多个Enums 的值存储在CoreData 和CloudKit 数据库中。

    要使其正常工作需要相当多的精确步骤。我在这里列出了我所学的效果很好。

    第 1 步:定义您的枚举:

    标记@objc、public和Int16

    @objc
    public enum SomeState: Int16 {
        case stateA
        case stateB
        case stateC
    }
    

    第 2 步:在您的 xcdatamodeld 中创建一个将存储 Enum 值的属性

    类型应该是Integer 16

    第 3 步:在 Data Model Inspector 中取消选中 Optional,并将默认值设置为 0

    这相当于Enum 的第一个索引。

    第 4 步:在父实体的 Data Model Inspector 中,将 Class Codegen 更改为 Manual/None

    第 5 步:创建 NSManaged 子类

    点击实体名称,然后从菜单栏中选择Editor > Create NSManagedObject Subclass。确保将 Target 设置为您的主项目。这将在项目导航器中创建两个新文件。

    MyObject+CoreDataClass.swift

    MyObject+CoreDataProperties.swift

    第 6 步:在 MyObject+CoreDataProperties.swift 文件中,将属性类型从 Int16 更改为您的 Enum 类型

    extension MyObject {
    
        @NSManaged public var state: SomeState
    
    }
    

    用法:

    设置/更新值:

    myObject.state = .stateA
    

    NSPredicate 搜索枚举值:

    NSPredicate(format: "state = %i", SomeState.stateA.rawValue)
    

    【讨论】:

      猜你喜欢
      • 2020-08-31
      • 2011-03-28
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多