Why doesn't image load on main thread?

北城以北 提交于 2019-12-11 17:48:31

问题


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)!
        }
    }
}
}

//in ViewController

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

回答1:


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
        }
    }
}


来源:https://stackoverflow.com/questions/47965917/why-doesnt-image-load-on-main-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!