2015-12-01 3 views
1

Поскольку вы не можете бросить Dictionary<String, AnyObject?> в NSDictionary напрямую, я хочу написать Dictionary расширения, которое будет делать, что преобразование (заменяющее NSNull для любых nil с).словарь расширения для преобразования нулевых значений NSNull

Но для этого расширение Dictionary должно быть ограничено до цифр, значениями которых являются Optional<T> where T:AnyObject. Как написать ограничение типа для этого?

ответ

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 
    } 
} 
+0

Благодарим вас, но нет никакого смысла в расширении словаря; ваши функции также могут быть глобальными. Функция-член будет намного лучшим способом реализации этого, поэтому мой вопрос о ограничениях типов. – phu

+0

@phu Эта функция выполняет именно то, что вы хотели. С какими более широкими ограничениями он должен работать? –

+0

Я не просил вас написать эту функцию; пожалуйста, перечитайте мой оригинальный вопрос. Я спрашиваю о ** ограничениях типа **. Например, «расширительный словарь, в котором значение: AnyObject» будет определять расширение, которое применяется только к dicts, значения которых реализуют «AnyObject». Я хочу знать, как создать расширение, которое применяется к dicts, значениями которых являются 'T? где T: AnyObject'. – phu

Смежные вопросы