Intereting Posts
Получение ошибки после обновления xcode 5.0 до 5.1 Удалить iAds из SKScene Повторное добавление subview в `UITableViewCell` повторяется iOS: выберите вкладку после того, как приложение загрузилось в делегат приложения создать диспетчер представлений под другим контроллером представлений UITableView и UISegmentedControl Добавление задержки в A для цикла без блокировки пользовательского интерфейса Как отобразить изображение выбранного UICollectioNViewCell в UIView? (Swift 3) При подклассификации RKObjectRequestOperation для проверки ошибок, как повторить неудачную операцию? nil __weak self – Почему это случилось? Программно загружать из магазина приложений Как создать дополнительный NSArray, который включает пары ключ-значение? UIAutomation с использованием командной строки не работает Анимация UISwitch вкл. / Выкл. Внутри пользовательского UITableViewCell Организуйте большой проект с несколькими частными кокоаподами

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

Я новичок в 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") } } } } }