本文介绍了Swift中的通用完成处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法,它有一个名为 performRequest()的方法。它需要一个 JSONRequest 参数。 JSONRequest 看起来像这样:

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

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

并且 performRequest()如下所示:

  public func performJSONRequest< T其中T:Entity>(jsonRequest:JSONRequest,_:Type){
//创建一个返回数据对象的请求
var entities = self.convertJSONData(data,jsonKey:jsonRequest.jsonKey,T.self)
//错误:'T'不等同于'Entity'
jsonRequest.completionHandler(entities,error)$正如你所看到的,它调用 convertJSONData()


$ b
,其格式如下:

  func convertJSONData< T其中T:Entity>(jsonData:AnyObject, :T.Type)→ [T] {
//将数据转换为Swift集合类,枚举它们并创建模型对象
var json = JSON(data:jsonData as NSData,options:nil,error:nil)
var entities = [T]()

在json中的obj {
let book = T(json:obj)
entities.append(book)
}

返回实体

Entity是一个协议, ,例如作者,符合。



它定义一个方法: init(json:JSON)。由于 T 定义为 T:Entity ,我可以调用 T: obj)创建符合 Entity 的任何类的实例。



能够使用 performJSONRequest()来执行对符合实体的任何对象的请求。例如,我想为这样的Book实例建立一个请求:

  var request = JSONRequest(endPoint:books) {(let object:[Entity] ?,让错误:NSError?) - > Void in 
//投射对象到[Book]并获得乐趣
}

performJSONRequest< Book>(请求)
pre>

我不能为我的生活找出我将如何实现这个。现在,我在 performJSONRequest()方法中遇到一个错误,说'T'不等于'Entity' 。如果我在完成处理程序中定义数组 [AnyObject] 我得到相同的错误:'T'不等同于'AnyObject' code>。



感谢任何帮助!

解决方案

解决方案是将通用类型移动到 JSONRequest class - that way JSONCompletionHandler 可以使用您要求的通用类型定义,而不仅仅是 Entity 协议。 (您的一些代码似乎有点伪装,所以这可能需要一些调整以适应您的实现。)



JSONRequest 现在是具有实体类型约束的通用类:

  public class JSONRequest< T:Entity> ;:请求{
//以`T`定义的完成处理程序
public typealias JSONCompletionHandler =([T]?,NSError?) - Void

//不再更改
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>){
//创建`T`数组
var entities:[T] = []
var error :NSError?

// completionHandler期望[T]?和NSError?
jsonRequest.completionHandler(entities,error)
}

code> JSONRequest 实例,在完成处理程序中给出的类型(例如, [Book]?)将设置类型 JSONRequest ,并保持整个过程:

  var request = JSONRequest 
}
performJSONRequest(request)


I have a method which has a method named performRequest(). It takes a JSONRequest parameter. JSONRequest looks something like this:

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

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

And performRequest() looks like this:

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)
}

As you can see, it calls convertJSONData() which looks like this:

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

Entity is a protocol which all my model classes, for example Author and Book, conform to.

It defines one method: init(json: JSON). Since T is defined as T:Entity, I can just call T:(json: obj) to create instances of any class conforming to Entity.

I want to be able to use performJSONRequest() to perform request for any object conforming to Entity. For example, I want to build a request for Book instances like this:

var request = JSONRequest(endPoint: "books") { (let object: [Entity]?, let error: NSError?) -> Void in
    // Cast object to [Book] and have fun
}

performJSONRequest<Book>(request)

I can't for the life of me find out how I would implement this. Right now, I get an error in the performJSONRequest() method saying 'T' is not identical to 'Entity'. If I define the array in the completion handler as [AnyObject] I get the same error: 'T' is not identical to 'AnyObject'.

Thanks for any help!

解决方案

The solution is to move the generic type up into the JSONRequest class - that way JSONCompletionHandler can be defined with the generic type you're requesting instead of just the Entity protocol. (Some of your code seemed a little pseudo-, so this might need some tweaking to fit back into your implementation.)

JSONRequest is now a generic class with an Entity type restraint:

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 doesn't need the type passed as a separate parameter any more. Since jsonRequest is specialized, it gets the type information from that parameter:

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)
}

When creating your JSONRequest instance, the type given in the completion handler (e.g., [Book]?) will set the type for the generic JSONRequest, and hold throughout the process:

var request = JSONRequest(endPoint: "books") { (books: [Book]?, error) in
    println(books?.count)
}
performJSONRequest(request)

这篇关于Swift中的通用完成处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-14 06:42