首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何(优雅地)使用关联值持久化Swift枚举-或者我应该避免使用它们?

如何(优雅地)使用关联值持久化Swift枚举-或者我应该避免使用它们?
EN

Stack Overflow用户
提问于 2016-06-01 17:20:53
回答 1查看 983关注 0票数 2

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

代码语言:javascript
复制
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
}

但是,我需要持久化包含枚举的Player类,而Realm和CoreData都没有任何简单的机制来实现这一点--可能是因为Objective-C中不能使用具有关联值的枚举(或者,对于Realm,在安卓中?)

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

有什么建议吗?

EN

回答 1

Stack Overflow用户

发布于 2016-06-01 22:02:47

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

我建议的解决方法如下所示:

将枚举值提取到属性。然后覆盖枚举的setter/getter,以便在每次设置/获取时将枚举值转换为属性。这看起来太复杂了,但用法非常简单,只需正常设置/获取status属性即可。

代码语言:javascript
复制
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"]
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37564445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档