我在下面的代码中遇到了一些崩溃。我认为崩溃是由块(LoadXZYAPI)转义和已经解除分配的ViewControllerA的访问属性引起的。因此,当strongSelf.data。*正在访问时,strongSelf返回nil或dealloc内存位置并导致崩溃。
每次尝试访问其属性(data。*)时,有没有办法防止此崩溃而不检查strongSelf?在不使LoadXZYAPI非转义的情况下,此方案中的最佳做法是什么?
提前致谢
class ViewControllerA {
var data: [String: Any]?
func loadData(){
LoadXZYAPI() { [weak self] (data:Any?) in
if let strongSelf = self {
strongSelf.data = data
DispatchQueue.global(qos:.default).asyc {
// process self.data
let imageData = GetImageData(data:strongSelf.data["image_name"])
if let data = data, let image = UIImage(data:imageData) {
DispatchQueue.main.async {
strongSelf.imageView = nil
strongSelf.imageView = CustomView(image: image) <-- Crashes randomly after this line
strongSelf.imageView!.width = strongSelf.map["width"] as? CGFloat
strongSelf.imageView!.height = strongSelf.map["height"] as? CGFloat
strongSelf.imageView!.backgroundColor = UIColor.init(hex: "#efefef")
strongSelf.imageViewWrapper.addSubview((strongSelf.imageView)!)
strongSelf.imageViewWrapper.bringSubview(toFront: (strongSelf.imageView)!)
strongSelf.imageView!.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
(strongSelf.imageView?.leadingAnchor)!.constraint(equalTo: (strongSelf.imageViewWrapper?.leadingAnchor)!),
(strongSelf.imageView?.trailingAnchor)!.constraint(equalTo: (strongSelf.imageViewWrapper?.trailingAnchor)!),
(strongSelf.imageView?.topAnchor)!.constraint(equalTo: (strongSelf.navigationController?.navigationBar.bottomAnchor)!),
(strongSelf.imageView?.bottomAnchor)!.constraint(equalTo: (strongSelf.imageViewWrapper?.bottomAnchor)!),
])
self?.didUpdateImageView()
}
}
}
}
}
}
}
答案 0 :(得分:1)
这应该是安全的:
func loadData(){
LoadXZYAPI() { [weak self] (data:Any?) in
//didn't bother putting a guard here since you don't need a strong ref here
self?.data = data
DispatchQueue.global(qos:.default).asyc {
guard let strongSelf1 = self else {
return
}
//use strongSelf1
DispatchQueue.main.async {
guard let strongSelf2 = self else {
return
}
//use strongSelf2
}
}
}
}
答案 1 :(得分:-1)
实际上你必须在每个闭包中捕获弱自我,如果你假设在加载过程中某个时候可能会关闭viewController
func loadData(){
LoadXZYAPI() { [weak self] (data:Any?) in
guard let strongSelf = self else {
return
}
strongSelf.data = data
DispatchQueue.global(qos: .default).async { [weak self] in
// process and manipulate self.data
DispatchQueue.main.async { [weak self] in
// Update UI
}
}
}
}