どハマりしました。
細かい経緯をすっ飛ばすと(いや明記しないと私のためにならないが)以下のサイトが参考になりました。
https://qiita.com/sensuikan1973/items/80ce3bd398cbbb8a4935
最終的に自分がつけたextensionは以下
extension UIImageView { func loadImageAsynchronously(url: String?, defaultUIImage: UIImage? = nil) -> Void { if url == nil { self.image = defaultUIImage return } DispatchQueue.global().async { do { PINCache.shared().object(forKey: url!) { (cache, key, object) in if let image = object as? UIImage { DispatchQueue.main.async { self.image = image } }else{ let storage = Storage.storage().reference().child(url!) storage.getData(maxSize: 1 * 1024 * 1024) { data, error in if let error = error { // Uh-oh, an error occurred! } else { // Data for "images/island.jpg" is returned let image = UIImage(data: data!)! PINCache.shared().setObject(image, forKey: url!) DispatchQueue.main.async { self.image = image } } } } } } catch { DispatchQueue.main.async { self.image = defaultUIImage } } } } }
引数はURLと言っていますが、PINCacheでキャッシュファイルを参照するためのキーを渡しています。
DispatchQueue.global().async でいま走っているスレッドを把握して
DispatchQueue.main.async にてmainスレッドを指してやります。
んだと思う。ここもうちょっと理解しないと、後で絶対困るな…