[英]Crash: While updating UIImageView using SDWebImage
我要实现的是,当用户单击任何CollectionViewCell时,将显示一个新视图以进行缩放和滚动 。 基本上,我有两个不同的类,分别名为MyCollectionViewController和MyScrollViewController。 我的集合视图控制器中有以下代码部分:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let VC = storyboard.instantiateViewController(withIdentifier: "myScrollVC") as? MyScrollViewController
self.navigationController?.pushViewController(VC!, animated: true)
VC?.setImageToScrollView(image_URL: (self.jsonData?.HD_WALLPAPER![indexPath.row].wallpaper_image)!)
}
我的滚动视图控制器中有以下代码部分:
import UIKit
import SDWebImage
class MyScrollViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet weak var myImageView: UIImageView!
@IBOutlet weak var myScrollView: UIScrollView!
override func viewDidLoad(){
super.viewDidLoad()
self.myScrollView.minimumZoomScale = 1.0
self.myScrollView.maximumZoomScale = 6.0
}
public func setImageToScrollView(image_URL: String){
DispatchQueue.main.async {
self.myImageView!.sd_setImage(with: URL(string: image_URL), completed: {
(image, error, cacheType, url) in
//Completion Block ... Do Nothing
})
}
}
override func didReceiveMemoryWarning(){
super.didReceiveMemoryWarning()
}
func viewForZooming(in scrollView: UIScrollView) -> UIView?{
return self.myImageView
}
}
我正在使用SDWebImage ...一个开放源代码库来管理图像缓存。
问题 :有时成功加载图像而没有任何错误,但是大多数情况下,我的应用在执行SDWebImage框架的sd_setImage api时崩溃 ,并显示以下错误……
致命错误:展开一个可选值时意外发现nil
查询 :
回到您的问题:
首先,我调用了pushViewController,然后调用了自定义函数。 从集合视图单元格调用函数是否正确?
答案是,在viewDidLoad之前,不要调用引用插座的函数。 这些插座是隐式解包的可选组件,但直到viewDidLoad才保证存在。 因此,您有比赛条件。 有时可以。
对其进行更改,以便您传递URL,但不要调用该函数:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let VC = storyboard.instantiateViewController(withIdentifier: "myScrollVC") as? MyScrollViewController
self.navigationController?.pushViewController(VC!, animated: true)
VC.imgURL = self.jsonData?.HD_WALLPAPER![indexPath.row].wallpaper_image)!
}
其中imgURL是MyScrollViewContainer上的实例变量。 然后从viewDidLoad调用函数,并传入imgURL。
override func viewDidLoad(){
super.viewDidLoad()
self.myScrollView.minimumZoomScale = 1.0
self.myScrollView.maximumZoomScale = 6.0
setImageToScrollView(image_URL: imgURL)
}
这将改变您的调用时间-确保在调用函数时插座确实存在。
===剩下的就是我以前的答案(仍然很重要,但是没有解决您的问题)===
您无需将SetImage调用包装在Dispatch.async中。 您的函数应为一行:
public func setImageToScrollView(image_URL: String){
self.myImageView.sd_setImage(with: URL(string: image_URL))
}
那应该使您的问题消失。 SetImage进行自己的调度,并且仅在出口仍然存在时才更新UI。
其他评论者指出了为什么您的代码有时会崩溃(当异步块完成时self.myImageView可能为nil)以及如何防范(如果让其绑定或警惕以检查UIImageView出口是否仍然存在)。 这些通常是相关的技术-但是SetImage会为您解决所有这些问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.