swift 语法解释。关闭?理解这段代码。可选不展开

swift syntax explanation. Closure? Understand this code. Optional not unwrapping

我正在尝试下载一些图片并在 Stack Overflow

上找到了解决方案

它使用了一些我不理解的闭包语法。

func getDataFromUrl(url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
    URLSession.shared.dataTask(with: url) { data, response, error in
        completion(data, response, error)
        }.resume()
}

它创建了一个函数,并且允许对完成参数进行转义,对吧?这个函数然后 return 是一个 URLSession? return 语句在哪里?

"data, response, error in" 语句是什么意思?

然后它调用一个叫做completion(...) 的函数,它是在哪里定义和实现的?

我猜这是一些我不知道的语法。关于在哪里阅读这个的任何提示?

然后我调用函数:

    getDataFromUrl(url: url){ data, response, error in
        guard let data = data, error == nil else {return}
        DispatchQueue.main.async {
            let image = UIImage(data: data)
            print(image!)
            self.m_images?.append(image!)
            print(self.m_images!.count)
        }
    }

self.m_images 是一个数组:[Any],在我的 viewController:

的顶部这样声明
var m_images:[Any]?=nil

解包时出现错误,它仍然是零:为什么?我只是附加了一张图片。图片确实存在,我打印出来效果很好。

completion 被声明为一个带有 3 个参数的闭包,并且在 getDataFromUrl 函数中没有 return 值。

 ... completion: @escaping (Data?, URLResponse?, Error?) -> () ...

闭包可以表示为

{ (data, response, error) -> Void in 
  // code 
}

在函数中调用completion传递参数

completion(data, response, error)

你的问题出现错误是因为 var m_images 被声明但没有初始化。目前您正在将对象附加到 nil 以防止代码崩溃。

基本上 从不 将数组声明为 [Any] 如果类型实际上更具体。

声明并初始化图像数组作为UIImage

的非可选数组
var mImages = [UIImage]()

然后检查是否可以使用可选绑定创建图像

if let image = UIImage(data: data) {
    print(image)
    self.mImages.append(image)
    print(self.mImages.count)
}

注意:与 PHP 或 JavaScript 不同,变量应该是 camelCased 而不是 snake_cased 在 Swift.