字典扩展将nil值转换为NSNull

时间:2015-12-01 21:07:22

标签: swift generics nsdictionary

由于您无法直接将Dictionary<String, AnyObject?>投射到NSDictionary,我想写一个Dictionary扩展名来进行转换(用NSNull代替任何{ {1}} S)。

但为了做到这一点,我的nil扩展程序必须限制为值为Dictionary的dicts。如何为此编写类型约束?

1 个答案:

答案 0 :(得分:1)

你不能将nil添加到dict中。所以你必须强迫它进行someType?,只需要你有一把钥匙。

Q/A借用OptionalConvertible解决方案:

protocol OptionalConvertible {
    typealias WrappedValueType = AnyObject
    func toOptional() -> WrappedValueType?
}

extension Optional: OptionalConvertible {
    typealias WrappedValueType = Wrapped

    // just to cast `Optional<Wrapped>` to `Wrapped?`
    func toOptional() -> WrappedValueType? {
        return self
    }
}
extension Dictionary where Value: OptionalConvertible, Key: NSCopying {
    //dict: Dictionary<Key, Optional<Value>>
    func convertToNSDictionary() -> NSDictionary {

        let mutableDict : NSMutableDictionary = NSMutableDictionary()

        for key in self.keys {
            if let maybeValue = self[key] {
                if let value = maybeValue.toOptional() {
                    mutableDict[key] = value as? AnyObject
                } else {
                    mutableDict[key] = NSNull()
                }
            }
        }
        return mutableDict

    }
}
var optionalObject : UIView? = nil

var dict : [NSString:AnyObject?] = [:]
dict["alpha"] = 1
dict["beta"] = 2
dict["delta"] = optionalObject as AnyObject? // force a nil into the dict

dict // ["beta": {Some 2}, "alpha": {Some 1}, "delta": nil]

let nsdict = dict.convertToNSDictionary() // ["alpha": 1, "beta": 2, "delta": {NSObject}]

或更实用的方法:

extension NSDictionary {

    static func fromDictionary<Key: Hashable, Value:AnyObject where Key: NSCopying>(dictionary:Dictionary<Key, Value>) -> NSDictionary {

        let mutableDict : NSMutableDictionary = NSMutableDictionary()

        for key in dictionary.keys {
            if let value = dictionary[key] {
                mutableDict[key] = value
            } else {
                mutableDict[key] = NSNull()
            }
        }
        return mutableDict
    }

    static func fromDictionary<Key: Hashable, Value:AnyObject where Key: NSCopying>(dict: Dictionary<Key, Optional<Value>>) -> NSDictionary {

        let mutableDict : NSMutableDictionary = NSMutableDictionary()

        for key in dict.keys {
            if let maybeValue = dict[key] {
                if let value = maybeValue {
                    mutableDict[key] = value
                } else {
                    mutableDict[key] = NSNull()
                }
            }
        }
        return mutableDict
    }
}