Ios 为什么即使在主线程上也需要使用DispatchQueue.main.async设置UIImageView.image

Ios 为什么即使在主线程上也需要使用DispatchQueue.main.async设置UIImageView.image,ios,swift,uikit,Ios,Swift,Uikit,当点击按钮时,尝试在按钮上设置图像。已验证始终在主线程上调用targetAction处理程序 这不管用 @objc func buttonTapped() { self.mybutton.imageView?.image = MyObjcClass.getImageNamed("DarkVersion") } 但这是可行的: @objc func buttonTapped() { DispatchQueue.main.async { // Does not work with

当点击按钮时,尝试在按钮上设置图像。已验证始终在主线程上调用targetAction处理程序

这不管用

@objc func buttonTapped() {
     self.mybutton.imageView?.image = MyObjcClass.getImageNamed("DarkVersion")
}
但这是可行的:

@objc func buttonTapped() {
    DispatchQueue.main.async { // Does not work without this dispatch
        self.mybutton.imageView?.image = MyObjcClass.getImageNamed("DarkVersion")
    }
}

在调试器上,我可以看到两者都在主线程上

将图像设置为按钮的正确方法是使用
setImage(\uimage:UIImage?,表示状态:UIControl.state)

当您使用直接访问设置图像时,按钮不知道它,并在状态更改例行程序中更改设置图像。
实际上,在buton的动作方法中,你不需要改变形象,你只需要
设置和的图像以在此方法中更改按钮的状态。按钮将选择合适的图像

视图控制器的正确代码应为:

class ViewController: UIViewController {
    @IBOutlet weak var myButton: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(buttonTapped))
        myButton.addGestureRecognizer(tapGesture)
    }

    @objc func buttonTapped() {
        self.myButton.setImage( MyObjcClass().getImageNamed("DarkVersion"), for: .normal)

    }
}

这项功能不会失败,区别在于
setImage
用于设置图像。

为了澄清,objcClass getImageNamed函数从主捆绑包加载图像。如果UIButton具有状态属性,为什么要使用如此困难的方法?