2015-12-09 47 views
2

我正在尝试定义一个协议,以便为几个Foundation类以及我自己的一些自定义类型添加一致性。我首先尝试在协议中使用便利初始值设定程序,但那does not seem possible。我在苹果开发论坛上的linked thread中读到他们谈论使用返回类型Self的类方法,但我无法弄清楚如何去做这件事。将基础类扩展为符合Swift协议

typealias JSONObject = AnyObject 
protocol JSONParseable { 
    static func fromJSONObject(jsonObject: JSONObject) throws -> Self 
} 

extension NSURL: JSONParseable { 
    class func fromJSONObject(jsonObject: JSONObject) throws -> Self { 
     guard let jsonString = jsonObject as? String else { 
      throw JSONParseError.ConversionError(message: "blah") 
     } 
     guard let result = NSURL(string: jsonString) else { 
      throw JSONParseError.ConversionError(message: "blah") 
     } 
     return result // Error: cannot convert return expression of type 'NSURL' to return type 'Self' 
    } 
} 

我发现了一个similar question但答案有纪念类为final - 我显然无法做到这一点的一个基础类。

有人可以解释如何解决我的方法上面?或者建议将协议一致性添加到基础类的不同方法?

+0

是的,谢谢!我使用self.init(...)方法。 –

+0

如果您喜欢答案,请不要忘记注册。 –

回答

2

使用self.init(....)而不是NSURL(....),因为这也需要为NSURL子类工作。

protocol JSONParseable { 
    static func fromJSONObject(jsonObject: JSONObject) throws -> Self 
} 

extension NSURL : JSONParseable { 

    class func fromJSONObject(jsonObject: JSONObject) throws -> Self { 

     guard let jsonString = jsonObject as? String else { 
      throw JSONParseError.ConversionError(message: "blah") 
     } 
     guard let result = self.init(string: jsonString) else { 
      throw JSONParseError.ConversionError(message: "blah") 
     } 
     return result 
    } 
} 

哈克:定义一个typealias T,这将返回一个NSURL甚至子类。

protocol JSONParseable { 
    typealias T = Self 
    static func fromJSONObject(jsonObject: JSONObject) throws -> T 
} 

extension NSURL : JSONParseable { 

    typealias T = NSURL 
    class func fromJSONObject(jsonObject: JSONObject) throws -> T { 

     guard let jsonString = jsonObject as? String else { 
      throw JSONParseError.ConversionError(message: "blah") 
     } 
     guard let result = NSURL(string: jsonString) else { 
      throw JSONParseError.ConversionError(message: "blah") 
     } 
     return result 
    } 
}