Intereting Posts
Запуск приложения iOS при перезагрузке устройства Получение уведомления APNS, но отсутствие отображения на устройстве в ios Swift – запуск приложения без push-уведомления iOS: Как передать модель из модели представления для просмотра модели с использованием MVVM? Не удалось вызвать вызов SSPI, см. Внутреннее исключение. контекст истек и больше не может использоваться Как я надежно обнаруживаю начало Y-кадра Yiview относительно экрана? Случаи Мне не нужно разворачивать Swift по желанию? Ошибка iPodMusicPlayer под ios 6.0.1? Сценарий раскадровки Xcode 4.5 Обновление свойств целевого объекта iOS из командной строки Правый CellIdentifier для ячейки в UITableView Кнопки не видны на экране Зеркало передней камеры iPhone Как запустить WKWebView без использования существующих файлов cookie Использование NSURLSessionDownloadTask для отображения изображения

Короткий простой код. Странное поведение

Я новичок в gcd и многопоточности / параллелизме / параллелизме. Я написал этот примерный проект, чтобы проверить некоторые вещи. У меня есть 3 метода, список URL-адресов изображений и imageView в интерфейсе.

Каждый метод делает практически одно и то же, с незначительными вариациями.

loadAllImagesSlow () перемещается по URL-адресам изображений, создавая NSData с каждого URL-адреса, создавая UIImage и устанавливая изображение imageView на это изображение.

loadAllImagesFast () отправляет эту целую задачу в глобальную параллельную очередь.

newMethod () перемещается по URL-адресам изображения и отправляет каждую задачу в глобальную параллельную очередь. Это был самый быстрый! : D Увлекательный материал. Для меня все равно.

Когда я запускаю loadAllImagesFast или newMethod, я вижу, что интерфейс быстро перемещается по каждому изображению, заканчиваясь последним. Но для loadAllImagesSlow я не вижу никаких изображений; только последнее изображение появляется в самом конце.

Я считаю, load_llImagesSlow работает в основном потоке (последовательная очередь), потому что я не получаю ответы при нажатии экрана (другие функции не блокируют пользовательский интерфейс). Но поскольку это очередная очередь, я не понимаю, почему ImageView не отображает изображения по одному. Поскольку основная очередь является последовательной, все должно быть выполнено до следующего кода. Но это не происходит с установкой образа imageView.

Любые идеи, почему это может быть? Мне это не нужно для конкретного проекта; Я просто пытаюсь понять поведение.

class ViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! var urlArray = [ "https://img0.ndsstatic.com/wallpapers/76df262f429c799124461286c5ee64b1_large.jpeg", "https://www.walldevil.com/wallpapers/a74/olivia-wilde-women-actresses-green-eyes-ponytails.jpg", "https://richestcelebrities.org/wp-content/uploads/2014/11/Olivia-Wilde-Net-Worth.jpg", "https://cdn.pcwallart.com/images/olivia-wilde-wallpaper-3.jpg", "https://kingofwallpapers.com/olivia-wilde/olivia-wilde-006.jpg", "https://img0.ndsstatic.com/wallpapers/b39ca6a58368a76a92d56739d6e2da31_large.jpeg" ] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap)) self.view.addGestureRecognizer(tapGesture) print("starting") self.loadAllImagesSlow() } func handleTap(sender: UITapGestureRecognizer) { print("tap") } func loadAllImagesSlow() { // takes around 4 seconds. UI is unresponsive throughout. Only last image gets shown let startTime = Date() for each in self.urlArray { let url = URL(string: each) do { let data = try Data(contentsOf: url!) self.imageView.image = UIImage(data: data) } catch { print("error") } } let endTime = Date() let executionTime = endTime.timeIntervalSince(startTime) print("Execution time: \(executionTime)") } func loadAllImagesFast() { // takes around 4 seconds, but UI is responsive! Cycles through the images! DispatchQueue.global(qos: .userInitiated).async { let startTime = Date() for each in self.urlArray { let url = URL(string: each) do { let data = try Data(contentsOf: url!) DispatchQueue.main.async { self.imageView.image = UIImage(data: data) } } catch { print("error") } } let endTime = Date() let executionTime = endTime.timeIntervalSince(startTime) print("Execution time: \(executionTime)") } } func newMethod() { // much much faster than 'loadAllImagesFast' // This method harnesses the power of the concurrent queue by dispatching lots of smaller tasks that run concurrently, rather than dispatching one large task that runs concorruntly alongside nothing else in that queue; essentially, sequientially, on a seaprate queue. for each in self.urlArray { DispatchQueue.global(qos: .userInitiated).async { let url = URL(string: each) do { let data = try Data(contentsOf: url!) DispatchQueue.main.async { self.imageView.image = UIImage(data: data) } } catch { print("error") } } } } }