为什么映像不会在主线程上加载? [英] Why doesn't image load on main thread?

查看:66
本文介绍了为什么映像不会在主线程上加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码从URL加载图像:加载/从Swift上的URL下载图像.很好.

I'm using this code to load an image from a URL: Loading/Downloading image from URL on Swift. That is working fine.

我已经从视图控制器中取出了代码,并将其放入了一个类中.现在,仅当我单步执行代码时,才会加载图像.我猜想这与代码运行正常有关,但是在图像完全从网络上下载之前,所有操作都已完成.

I've take the code out of the viewcontroller and put it into a class. Now the image only loads when I step through the code. I'm guessing this has something to do with the code running fine but everything finishes executing before the image has completely downloaded from the web.

我遗漏了哪一部分,因此代码等待图像而不会占用在视图控制器中执行的任何其他代码?

What piece of this am I missing so the code waits for the image without holding up any other code executing in the viewcontroller?

class MyClass:NSObject {

private var myImage:UIImage = UIImage()

func getMyImage() -> UIImage {
    if let url = URL(string: self.myUrl) {
            self.myImage = self.downloadImage(url: url)
    }
    return self.myImage
}

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

func downloadImage(url: URL) {
    print("Download Started")
    getDataFromUrl(url: url) { data, response, error in
        guard let data = data, error == nil else { return }
        print(response?.suggestedFilename ?? url.lastPathComponent)
        print("Download Finished")
        DispatchQueue.main.async() {
            self.myImage = UIImage(data: data)!
        }
    }
}
}

//在ViewController中

//in ViewController

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    DispatchQueue.main.async() {
        self.theImageView.image = self.myClass?.getImage()
    }
}

推荐答案

异步调用完成后,您必须设置imageView的图像.

You have to set up the imageView's image once the asynchronous call back is completed.

class MyClass: NSObject {
    // async function
    func getMyImage(completion: @escaping (UIImage?) -> Void) {
        // if the url is not available, completion with null
        guard let url = URL(string: self.myUrl) else { 
            completion(nil)
            return 
        }

        getDataFromUrl(url: url) { data, response, error in
            // if something goes wrong, completion with null
            guard let data = data, error == nil else { 
                completion(nil)
                return 
            }
            print(response?.suggestedFilename ?? url.lastPathComponent)
            print("Download Finished")
            completion(UIImage(data: data)!)
        }
    }
}

// in ViewController
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    getImage { image in 
        // async function will get called when image is ready
        DispatchQueue.main.async() { // set up your view in main thread
            self.theImageView.image = image
        }
    }
}

这篇关于为什么映像不会在主线程上加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆