为什么不在主线程上加载图像?

问题描述 投票:0回答:1

我正在使用此代码从URL加载图像:Loading/Downloading image from URL on Swift。这工作正常。

我将代码从viewcontroller中取出并放入一个类中。现在,只有在我单步执行代码时才会加载图像。我猜这与运行正常的代码有关,但是一切都在图像完全从网上下载之前完成。

我错过了什么,所以代码等待图像而没有阻止在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中

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    DispatchQueue.main.async() {
        self.theImageView.image = self.myClass?.getImage()
    }
}
swift asynchronous uiimageview uiimage
1个回答
1
投票

异步回调完成后,您必须设置imageView图像。

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
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.