iOS lazy var UIBarButtonItem目标问题
当使用lazy var初始化时,我无意识地发现了这个UIBarButtonItem目标问题。
class ViewController: UIViewController { lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(action1)) lazy var barButtonItem2: UIBarButtonItem = { let barButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(action2)) return barButtonItem } override func viewDidLoad() { super.viewDidLoad() print(barButtonItem1.target, barButtonItem2.target) } }
打印结果显示barButtonItem1.target为零,而barButtonItem2.target为自己,这看起来很疯狂! 当我使用barButtonItem1的lazy var写入时,我得到了这个问题,然后我发现barButtonItem1的动作永远不会被调用,最后问题是barButtonItem1.target为零。
我不知道为什么会发生这种情况,但是我很确定这是一个错误。 有没有人知道这件事? 如果你能解释一下,我会非常感激。
下面的解释是我的猜测 。 不幸的是,我没有足够的声誉发表评论,所以让我给你一个答案。
我的猜测:这是一个编译器错误。
首先,我制作了一个UIBarButtonItem的小扩展。 (第二个参数不是Any?
但UIViewController?
)
extension UIBarButtonItem { convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem, targetViewController: UIViewController?, action: Selector?) { // call the initializer provided by UIKit self.init(barButtonSystemItem: systemItem, target: targetViewController, action: action) } }
然后我尝试用下面的代码初始化惰性存储的variables。
class ViewController: UIViewController { lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action)) override func viewDidLoad() { super.viewDidLoad() print(barButtonItem1.target) } func action() { } }
然后编译器提出错误,并说
无法将types'(NSObject) – >() – > ViewController'的值转换为期望的参数types“UIViewController?”
这表明编译器无法确定self
是ViewController
。 (由UIKit提供的初始化器会编译,因为第二个参数是Any?
它接受types(NSObject) -> () -> ViewController
。
但是,当给types注释的懒惰variables
lazy var barButtonItem1: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action))
源代码愉快编译和barButtonItem1.target
被设置为self
。
我相信types注释帮助编译。 以上是我猜你遇到的问题是由编译器错误引起的。
另请参阅:有报告类似于您遇到的问题的问题。 它们都是编译器错误。
斯威夫特懒惰使用自我实例化
使用懒惰实例化时input推理