2016-02-02 3 views
1

Чтобы использовать NSCoding с типом Enum Свифта я сделал расширение на NSCoder:Generic типа RawRepresentable ошибочно интерпретируется как само это кажется

extension NSCoder { 
    func encodeEnum<Enum: RawRepresentable where Enum.RawValue == String>(value: Enum, forKey key: String) { 
     self.encodeObject(value.rawValue, forKey: key) 
    } 

    func decodeEnumForKey<Enum: RawRepresentable where Enum.RawValue == String>(key: String) -> Enum? { 
     guard let returnValue = self.decodeObjectForKey(key) as? String else { return nil } 
     return Enum(rawValue: returnValue) 
    } 
} 

Метод encodeEnum прекрасно работает для String -backed Enum, но когда я пытаюсь декодировать предварительно кодированный Enum так:

enum MyEnum: String { case Something, Other } 
class MyEnumClass: NSObject, NSCoding { 
    let myEnum: MyEnum 

    init(myEnum: MyEnum) { 
     self.myEnum = myEnum 
    } 

    required convenience init?(coder aDecoder: NSCoder) { 
     guard let tmp = aDecoder.decodeEnumForKey("myKey") as? MyEnum else { return nil } 

     self.init(myEnum: tmp) 
    } 
} 

Я получаю сообщение об ошибке на aDecoder.decodeEnumForKey("myKey"):

Value of type `NSCoder` has no member `RawValue` 

Я уверен, что это имеет какое-то отношение к родовому и состоянию, которое Enum.RawValue == String. Но я не понимаю, пока он не работает, но работает для encodeEnum().

ответ

1

Проблема заключается в том, что в

guard let tmp = aDecoder.decodeEnumForKey("myKey") as? MyEnum else { return nil } 

компилятор не может вывести общий заполнитель из

func decodeEnumForKey<Enum: ...>(key: String) -> Enum? 

быть MyEnum, вы должны привести результат к MyEnum? вместо:

guard let tmp = aDecoder.decodeEnumForKey("myKey") as MyEnum? else { return nil } 

так, чтобы возвращаемый тип был выведен как MyEnum? из контекста вызова.

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