我们在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类中,我想使用数据对象,但引用friendStatus
作为FriendStatus
enum,所以我最后用了很多.rawValue
。例如
RandomClass.swift
if (dataObject.friendStatus == FriendStatus.PendingIncoming.rawValue) {
// do something
}
这可以工作,并且可以说这是相对较小的,但是在所有地方使用.rawValue
似乎令人讨厌(tm)。是否有一种方法来做转换,所以DataObject.friendStatus
是真正的一个FriendStatus enum,我可以停止使用.rawValue
在swift?
不幸的是,由于我的模型(DataObject)是现有代码,因此我可以对其进行的更改受到限制。
因为NSNumber
和NSInteger
不一样。NSNumber
是引用类型,而NSInteger
是值类型,根据您的平台解析为Int32
或Int64
。
告诉Swift如何比较NSNumber
和FriendStatus
:
public func == (lhs: NSNumber, rhs: FriendStatus) -> Bool {
return lhs.integerValue == rhs.rawValue
}
public func == (lhs: FriendStatus, rhs: NSNumber) -> Bool {
return rhs.integerValue == lhs.rawValue
}
您可以为DataObject类定义一个扩展,该扩展定义一个getter来为您执行展开操作。
extension DataObject {
var friendStatusEnum: FriendStatus {
return FriendStatus(rawValue: friendStatus.integerValue)!
}
}
注意,它隐式地展开enum,这意味着如果由于某种原因NSNumber的值与enum不匹配,它将崩溃。一个更健壮的版本会从init中检查nil并返回一个合理的默认值。