Swift:具有符合协议的实例的完成闭包

Posted

技术标签:

【中文标题】Swift:具有符合协议的实例的完成闭包【英文标题】:Swift: Completion closures with instances that conforms to protocol 【发布时间】:2014-06-12 19:39:47 【问题描述】:

在调用异步请求时,我尝试使用 Swift 的 闭包,就像 ObjC 中的完成块一样。 这似乎有效。我正在为我的模型类使用protocol,并与Array 结合使用我遇到了问题。相关代码:

//ModelProtocol.swift
protocol ModelProtocol 
    // all my models should implement `all`
    class func all(completion: ((models: Array<ModelProtocol>) -> Void) )


//Person.swift
// calls the HTTP request and should return all Person-Objects in `completion` 
class func all(completion: ((models: Array<ModelProtocol>) -> Void) )  

    let request = HTTPRequest()
    request.getAll()  (data:NSArray) in
        var persons:Person[] = //... `data` is the result from the HTTP GET request and will be parsed here - this is ok
        completion(models: persons)
    


//HTTPRequest.swift
func getAll(completion: ((data: NSArray) -> Void) )  
    //... some setup would be here
    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) (response, data, error) in

        var jsonResponse: NSArray = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray

        completion(data: jsonResponse)
    


//ViewController.swift
override func viewDidLoad() 
    super.viewDidLoad()

    // use this whole code here - receive all Persons and show in a tableView or something like this
    Person.all(  (models: Array<ModelProtocol>) in
        println(models) //CRASH here
        )

当我将函数 allprotocol 定义(以及 Person.swift 中的函数 all)更改为 class func all(completion: ((models: Person[]) -&gt; Void) ) 时,它正在工作。

但我想使用Array&lt;ModelProtocol&gt; 来使用多态性,并且只使用符合ModelProtocol 的类,可以是PersonHouse 或其他。

我想我在这里遗漏了一些重要或基本的东西。我希望我的问题足够清楚。

编辑

ViewController.swift 中,应用程序的执行在println(models) 语句处停止,消息为EXC_BAD_ACCESS

【问题讨论】:

能否请您发布崩溃的错误信息? 你试过ModelProtocol[]而不是Array&lt;ModelProtocol&gt;吗? ModelProtocol[] 给出同样的错误信息 【参考方案1】:

也许这会做你想要的:

protocol ModelProtocol 
    // all my models should implement `all`
    class func all(completion: ((models: Array<Self>) -> Void) )


class func all(completion: ((models: Array<Person>) -> Void) )  

    let request = HTTPRequest()
    request.getAll()  (data:NSArray) in
        var persons:Person[] = //... `data` is the result from the HTTP GET request and will be parsed here - this is ok
        completion(models: persons)
    

【讨论】:

以上是关于Swift:具有符合协议的实例的完成闭包的主要内容,如果未能解决你的问题,请参考以下文章

具有泛型的Swift函数,其中约束是自身符合的协议

Swift - 从闭包内返回变量

Swift 完成处理程序 - 转义尾随闭包

Swift 闭包完成处理程序

Swift-使用完成处理程序更新闭包外的全局变量

iOS/Swift - 闭包/完成块和委托/函数有啥区别?