我有一个方法,它有一个名为performRequest()的方法。它需要一个JSONRequest参数。JSONRequest如下所示:

public typealias JSONCompletionHandler = ([Entity]?, NSError?) -> Void

public class JSONRequest: Request {
    public var completionHandler: JSONCompletionHandler
    public var endPoint: String
}

performRequest()如下:
public func performJSONRequest<T where T: Entity>(jsonRequest: JSONRequest, _: Type) {
        // Make a request which returns a data object
        var entities = self.convertJSONData(data, jsonKey: jsonRequest.jsonKey, T.self)
        // Error: 'T' is not identical to 'Entity'
        jsonRequest.completionHandler(entities, error)
}

如您所见,它调用convertJSONData()如下:
func convertJSONData<T where T: Entity>(jsonData: AnyObject, _: T.Type) -> [T] {
        // Convert the data into Swift collection classes, enumerate over them, and create model objects
        var json = JSON(data: jsonData as NSData, options: nil, error: nil)
        var entities = [T]()

        for obj in json {
            let book = T(json: obj)
            entities.append(book)
        }

    return entities

实体是我的所有模型类(例如AuthorBook)都符合的协议。
它定义了一个方法:init(json: JSON)。因为T被定义为T:Entity,所以我可以调用T:(json: obj)来创建符合Entity的任何类的实例。
我希望能够使用performJSONRequest()对符合实体的任何对象执行请求。例如,我想构建这样的图书实例请求:
var request = JSONRequest(endPoint: "books") { (let object: [Entity]?, let error: NSError?) -> Void in
    // Cast object to [Book] and have fun
}

performJSONRequest<Book>(request)

我一辈子都找不到如何实现这一点。现在,我在说performJSONRequest()的方法中得到一个错误。如果我将完成处理程序中的数组定义为'T' is not identical to 'Entity'则会得到相同的错误:[AnyObject]
谢谢你的帮助!

最佳答案

解决方案是将泛型类型向上移动到JSONRequest类中,这样就可以用您请求的泛型类型来定义JSONCompletionHandler而不仅仅是Entity协议。(您的一些代码看起来有点伪-因此可能需要进行一些调整以适应您的实现。)
JSONRequest现在是具有Entity类型约束的通用类:

public class JSONRequest<T: Entity>: Request {
    // completion handler defined in terms of `T`
    public typealias JSONCompletionHandler = ([T]?, NSError?) -> Void

    // no further changes
    public var completionHandler: JSONCompletionHandler
    public var endPoint: String
    public init(endPoint: String, completionHandler: JSONCompletionHandler) {
        self.endPoint = endPoint
        self.completionHandler = completionHandler
    }
}

performJSONRequest不再需要将类型作为单独的参数传递。由于jsonRequest是专门化的,因此它从该参数获取类型信息:
public func performJSONRequest<T: Entity>(jsonRequest: JSONRequest<T>) {
    // create array of `T` somehow
    var entities: [T] = []
    var error: NSError?

    // completionHandler expects [T]? and NSError?
    jsonRequest.completionHandler(entities, error)
}

创建JSONRequest实例时,完成处理程序中给定的类型(例如,[Book]?)将设置通用的类型,并在整个过程中保持:
var request = JSONRequest(endPoint: "books") { (books: [Book]?, error) in
    println(books?.count)
}
performJSONRequest(request)

10-05 21:52