我希望能够将某个协议(protocol)类型的类(不是初始化对象)传递给一个方法,然后在方法中调用该类的类函数。代码如下。
我正在使用 Swift 并且有一个这样定义的协议(protocol)
//Protocol for any object to be used with an FAUAPIConnection
protocol FAUAPIModel{
//Used to parse the object from a given dictionary to an object
class func parseFromJSON(JSON:AnyObject) -> Self
//Required default init
init()
}
我想做的就是有这样的方法
func getSomeParsingDone<T:FAUAPIModel>(model:T.Type? = nil, getPath:path, callingObj:CallingClass) -> Void
{
//GetIt is inconsequential, just logic to get an object from a certain path
var returnObj:AnyObject = GetIt.get(path)
if(model != nil){
returnObj = model!.parseFromJSON() <<<<<< Type 'T' does not conform to protocol 'AnyObject'
}
callingObj.done(returnObj)
}
实现协议(protocol)的对象
import Foundation
class MyObj: FAUAPIModel{
var neededVal:String
var nonneededVal:String
required convenience init(){
self.init(neededVal:"VALUE")
}
init(neededVal:String, nonneededVal:String = ""){
self.neededVal = neededVal
self.nonneededVal = nonneededVal
}
class func parseFromJSON(JSON:AnyObject) -> WGMPart
{
return WGMPart() <<<<<<<< Method 'parseFromJSON' in non-final class 'WGMPart' must return 'Self' to conform to protocol 'FAUAPIModel'
}
}
但是,我不断收到两个错误。我在上面用 '<<<<<<<<<<<<'
指出了这些编译错误。
请您参考如下方法:
这里有很多小事需要考虑,但让我们直奔问题的核心。您想要的签名如下所示:
func getSomeParsingDone<T:FAUAPIModel>(model:T.Type, path:String) -> T?
我将 return 设为可选,因为这里有很多事情可能会失败,你真的不应该把所有这些都变成崩溃。
我建议您的协议(protocol)如下所示:
protocol FAUAPIModel {
class func parseFromJSON(JSON:AnyObject) -> Self
}
这样,您就可以保证返回自己的类,而不仅仅是任何可解析的类。这确实意味着您需要将您的类设置为 final。如果你不希望它们是final,你需要 promise 一些init方法来构造它。参见 Protocol func returning Self了解有关如何在需要时处理该问题的更多详细信息。
所以把它放在一起,在实践中可能看起来像这样:
protocol FAUAPIModel {
class func parseFromJSON(JSON:AnyObject) -> Self
}
func createObjectOfClass<T: FAUAPIModel>(model: T.Type, path: String) -> T? {
if let json: AnyObject = GetJSON(path) {
return model.parseFromJSON(json)
}
return nil
}
// Bogus JSON reader
func GetJSON(path: String) -> AnyObject? {
let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(path.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!, options: NSJSONReadingOptions(0), error: nil)
return json
}
// Bogus model class that returns trivial version of itself
final class Something: FAUAPIModel {
class func parseFromJSON(JSON:AnyObject) -> Something {
return Something()
}
}
// Using it
let something = createObjectOfClass(Something.self, "/path/to/file")
