Быстрое объяснение синтаксиса. Закрытие? Поймите этот код. Необязательный не распаковка

Я пытаюсь загрузить некоторые изображения и нашел решение по переполнению стека

Это использует некоторый синтаксис замыкания, который я не понимаю.

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

Он создает функцию, и ему разрешено экранировать аргумент завершения, верно? Эта функция затем возвращает URLSession? где возврат заявления?

Что означает выражение "данные, ответ, ошибка в"?

Затем он вызывает функцию с именем завершение (...), где она определена и реализована?

Я предполагаю, что это какой-то синтаксис, которого я не знаю. Любой намек на то, где почитать об этом?

Затем я вызвал функцию:

    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

Я получаю сообщение об ошибке при развертывании, но все равно ноль: почему? Я только что добавил изображение. Изображение существует, я его печатаю, и оно отлично работает.

1 ответ

Решение

completion объявляется как замыкание, принимая 3 параметра и не возвращая значение в getDataFromUrl функция.

 ... 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 переменные в Swift должны иметь значение camelCased, а не snake_cased.

Другие вопросы по тегам