【问题标题】:How to (elegantly) persist Swift enum with associated values - or should I avoid them?如何(优雅地)将 Swift 枚举与相关值保持一致——或者我应该避免使用它们吗?
【发布时间】:2016-06-01 09:20:52
【问题描述】:

我被 Swift 的出色表现力所吸引,并打算为每个案例使用一个带有关联值的枚举,例如:

enum PlayerStatus {
    case Playing (league: Int, position: Int)
    case NotPlaying (ReasonNotPlaying, LastPlayed)
}

enum ReasonNotPlaying {
    case Injured
    case Away
    case DidntPlay
    case Left
}

struct LastPlayed {
    let year: Int
    let position: Int
}

class Player {

    var firstName: String = ""
    var surname: String = ""
    //  etc

    var status: PlayerStatus? = nil
}

但是,我需要 PERSIST 包含枚举的 Player 类,Realm 和 CoreData 都没有任何简单的机制来执行此操作 - 可能是因为具有关联值的枚举在 Objective-C 中不可用(或者,在Realm,在 Android 中?)

我误解了枚举吗?我的例子可能不清楚吗?或者我怎样才能简洁地持久化枚举?

有什么建议吗?

【问题讨论】:

    标签: swift core-data enums realm


    【解决方案1】:

    你是对的。目前,Realm 不支持存储 Enum。因此,没有简单的方法可以直接存储具有关联值的 Enum。

    我建议的解决方法如下:

    将枚举值提取到属性。然后覆盖枚举的 setter/getter 以将枚举值转换为每个 set/get 的属性。看起来太复杂了,其实用法很简单,正常设置/获取status属性即可。

    enum PlayerStatus {
        case Playing (league: Int, position: Int)
        case NotPlaying (ReasonNotPlaying, LastPlayed)
    }
    
    enum ReasonNotPlaying: String {
        case Injured
        case Away
        case DidntPlay
        case Left
    }
    
    struct LastPlayed {
        let year: Int
        let position: Int
    }
    
    class Player: Object {
        dynamic var firstName: String = ""
        dynamic var surname: String = ""
        //  etc
    
        private let playingLeague = RealmOptional<Int>()
        private let playingPosition = RealmOptional<Int>()
    
        private dynamic var reasonNotPlaying: String? = nil
    
        private let lastPlayedYear = RealmOptional<Int>()
        private let lastPlayedPosition = RealmOptional<Int>()
    
        var status: PlayerStatus? {
            get {
                if let league = playingLeague.value,
                    let position = playingPosition.value {
                    return PlayerStatus.Playing(league: league, position: position)
                } else if let year = lastPlayedYear.value,
                    let position = lastPlayedPosition.value,
                    let reason = reasonNotPlaying {
                    return PlayerStatus.NotPlaying(ReasonNotPlaying(rawValue: reason)!,
                                                   LastPlayed(year: year, position: position))
                }
                return nil
            }
            set {
                if let newValue = newValue {
                    switch newValue {
                    case let .Playing(league, position):
                        playingLeague.value = league
                        playingPosition.value = position
    
                        reasonNotPlaying = nil
                        lastPlayedYear.value = nil
                        lastPlayedPosition.value = nil
                    case let .NotPlaying(reason, lastPlayed):
                        playingLeague.value = nil
                        playingPosition.value = nil
    
                        reasonNotPlaying = reason.rawValue
                        lastPlayedYear.value = lastPlayed.year
                        lastPlayedPosition.value = lastPlayed.position
                    }
                } else {
                    playingLeague.value = nil
                    playingPosition.value = nil
    
                    reasonNotPlaying = nil
                    lastPlayedYear.value = nil
                    lastPlayedPosition.value = nil
                }
            }
        }
    
        override static func ignoredProperties() -> [String] {
            return ["status"]
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-24
      • 2011-08-14
      • 2018-10-26
      • 2019-07-06
      • 2010-09-11
      • 1970-01-01
      • 2022-08-05
      相关资源
      最近更新 更多