【问题标题】:Adding a completion block to a fuction in Swift [closed]在 Swift 中向函数添加完成块 [关闭]
【发布时间】:2016-02-07 19:24:46
【问题描述】:

我是 Swift 新手,我正在尝试添加一个完成块。我记得这在objective-c中非常简单,但是我对这里的语法有点迷失了。此函数解析一些 json 并将相关内容添加到数组中。功能完成后,我需要刷新表格视图,因为我无法在需要添加完成块的块内执行此操作。

如何在 Swift 中为这个函数添加一个完成块,以及新的方法调用是什么样的?

func getSetParameter()
{
    let param = ["format":"json"]
    let jsonUrl: String! = "http://somewebsite.com"

    let manager: AFHTTPSessionManager = AFHTTPSessionManager()
    manager.GET(jsonUrl, parameters: param, success: {
        (task: NSURLSessionDataTask!, JSONResponse: AnyObject!) in

            let responseDictionary = JSONResponse as! NSDictionary
            let responseArray = responseDictionary.objectForKey("response") as! NSArray
            for thumbnailsOnVideoDictionary in responseArray
            {
                let thumbnailsOnVideoArray = thumbnailsOnVideoDictionary.objectForKey("thumbnails") as! NSArray
                if thumbnailsOnVideoArray.count == 0 {
                    self.thumbnails.append(nil)
                }
                else {
                    let smallThumbnail = thumbnailsOnVideoArray[1];
                    let aspect_ratio: Float = (smallThumbnail.objectForKey("aspect_ratio") as! Float)
                    let height: UInt = (smallThumbnail.objectForKey("height") as! UInt)
                    let name: AnyObject = smallThumbnail.objectForKey("name")!
                    let url: String = (smallThumbnail.objectForKey("url") as! String)
                    let width: UInt = (smallThumbnail.objectForKey("width") as! UInt)

                    let newThumbnail = Thumbnail(aspect_ratio: aspect_ratio, height: height, name: name, url: url, width: width)
                    self.thumbnails.append(newThumbnail)
                }
            }
        }, failure: {(task: NSURLSessionDataTask?, error: NSError!) in

    })
}

【问题讨论】:

标签: swift syntax objective-c-blocks


【解决方案1】:

使用handler 的参数更新您的函数。在这个例子中,我使用了一个传递缩略图数组的闭包,并且什么都不返回:

func getSetParameter(handler:([Thumbnail]) -> ()) {

    // generate an array of Thumbnails
    let someArray = [Thumbnail(), Thumbnail()]

    // call the handler, passing the array
    handler(someArray)
}

由于最后一个参数是一个闭包,你可以使用 Swift 的尾随闭包语法:

// call the function

getSetParameter { thumbnails in
    print(thumbnails)
}

或者更简洁:

getSetParameter {
    print($0)
}

更详细的版本(没有尾随闭包语法)也可以:

getSetParameter({ (thumbnails) -> () in
    print(thumbnails)
})

但在我看来,这更丑陋。

【讨论】:

  • 我刚试过这个,但我不确定处理程序与完成块有什么相似之处。
【解决方案2】:

不确定如何将闭包与处理程序一起使用,self.getSetParameter 函数括号中的代码在函数本身之前被调用。而不是在函数完成时。

override func viewDidLoad()
{
    self.getSetParameter { (thumbnails: [Thumbnail?]) -> () in
        for var index = 0; index < thumbnails.count; ++index {
            let currentThumbnail = thumbnails[index]

            var title: String
            var image: UIImage
            if currentThumbnail!.isKindOfClass(Thumbnail) {
                title = "Title " + String(index)
                image = currentThumbnail!.image
            }
            else {
                title = "Nil"
                image = UIImage(named: "image0")!
            }

            self.models.append(CustomCell(title: title, image: image))
        }
    }
}

func getSetParameter(handler:([Thumbnail?]) -> ()) {
    var thumbnails = [Thumbnail?]()
    let param = ["format":"json"]
    let jsonUrl: String! = "http://somewebsite.com"

    let manager: AFHTTPSessionManager = AFHTTPSessionManager()
    manager.GET(jsonUrl, parameters: param, success: {
        (task: NSURLSessionDataTask!, JSONResponse: AnyObject!) in

            let responseDictionary = JSONResponse as! NSDictionary
            let responseArray = responseDictionary.objectForKey("response") as! NSArray
            for thumbnailsOnVideoDictionary in responseArray
            {
                let thumbnailsOnVideoArray = thumbnailsOnVideoDictionary.objectForKey("thumbnails") as! NSArray
                if thumbnailsOnVideoArray.count == 0 {
                    thumbnails.append(nil)
                }
                else {
                    let smallThumbnail = thumbnailsOnVideoArray[1];
                    let aspect_ratio: Float = (smallThumbnail.objectForKey("aspect_ratio") as! Float)
                    let height: UInt = (smallThumbnail.objectForKey("height") as! UInt)
                    let name: AnyObject = smallThumbnail.objectForKey("name")!
                    let url: String = (smallThumbnail.objectForKey("url") as! String)
                    let width: UInt = (smallThumbnail.objectForKey("width") as! UInt)

                    let newThumbnail = Thumbnail(aspect_ratio: aspect_ratio, height: height, name: name, url: url, width: width)
                    thumbnails.append(newThumbnail)
                }
                handler(thumbnails)
            }
        }, failure: {(task: NSURLSessionDataTask?, error: NSError!) in

    })
}

【讨论】:

  • 这会多次调用handler,这是出乎意料的。尝试将handler 移到for 循环之外,以便在循环完成后调用它。此外,最好不要在处理程序中使用可选项,这样您以后就不必打开它们了。
猜你喜欢
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多