在不使用rawValue的情况下比较Swift中的NSNumber属性包装NS_ENUM

时间:2016-07-01 16:39:45

标签: objective-c swift enums

我们在ObjC中有一些现有代码可以进行JSON序列化/反序列化。在其中一个数据对象的.h文件中,我们有类似的内容:

DataObject.h

@class DataObject
typedef NS_ENUM(NSInteger, FriendStatus)
{
    FriendStatusMyself = -1,
    FriendStatusNotFriends = 0,
    FriendStatusFriends = 1,
    FriendStatusPendingIncoming = 2,
    FriendStatusPendingOutgoing = 3
};

@interface DataObject : MTLModel <MTLJSONSerializing>

@property (nonatomic, strong) NSNumber *friendStatus;
// more stuff...
@end

现在,这适用于JSON序列化,所有这些都适用于全世界。好吧。

在我的swift类中,我想使用DataObject,但引用friendStatus作为 FriendStatus枚举,所以我最终使用了.rawValue。例如

RandomClass.swift

if (dataObject.friendStatus == FriendStatus.PendingIncoming.rawValue) {
    // do something
}

这是有效的,可以说这是相对较小的,但在整个地方使用.rawValue似乎很难看(tm)。有没有办法进行转换,所以DataObject.friendStatus真的是一个FriendStatus枚举,我可以在swift中停止使用.rawValue

不幸的是,我对我的模型(DataObject)所做的更改有限,因为它是现有的代码。

2 个答案:

答案 0 :(得分:3)

因为NSNumberNSInteger不同。 NSNumber是引用类型,而NSInteger是值类型,根据您的平台,它会解析为Int32Int64

告诉Swift如何将NSNumberFriendStatus进行比较:

public func == (lhs: NSNumber, rhs: FriendStatus) -> Bool {
    return lhs.integerValue == rhs.rawValue
}

public func == (lhs: FriendStatus, rhs: NSNumber) -> Bool {
    return rhs.integerValue == lhs.rawValue
}

答案 1 :(得分:2)

您可以为DataObject类定义一个扩展,它定义一个getter来为您解包。

extension DataObject {
    var friendStatusEnum: FriendStatus {
        return FriendStatus(rawValue: friendStatus.integerValue)!
    }
}

请注意,它隐式地展开枚举,这意味着如果由于某种原因NSNumber的值与枚举不匹配,它将崩溃。更强大的版本将从init检查nil并返回合理的默认值。