悟空之*_*空之空 5 lazy-evaluation target uibarbuttonitem ios swift
我在使用惰性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)
}
}
Run Code Online (Sandbox Code Playgroud)
打印结果显示barButtonItem1.target为零,barButtonItem2.target为self,这看起来很疯狂!当我使用barButtonItem1的懒惰var写时我得到了这个问题,然后我发现barButtonItem1的动作永远不会被调用,最后问题是barButtonItem1.target为零.
我不知道为什么会这样,但我很确定这是一个错误.有谁知道这件事?如果你能解释一下,我将非常感激.
小智 3
下面的解释是我的猜测。不幸的是,我没有足够的声誉来发表评论,所以让我给你一个答案。
我的猜测:这是一个编译器错误。
首先,我制作了 UIBarButtonItem 的一个小型扩展。(第二个参数不是Any?but 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)
}
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试使用下面的代码初始化惰性存储变量。
class ViewController: UIViewController {
lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action))
override func viewDidLoad() {
super.viewDidLoad()
print(barButtonItem1.target)
}
func action() { }
}
Run Code Online (Sandbox Code Playgroud)
然后编译器抛出错误并说
无法将类型“(NSObject) -> () -> ViewController”的值转换为预期的参数类型“UIViewController?”
这表明编译器无法确定它self是ViewController. (UIKit 提供的初始值设定项会编译,因为第二个参数Any?接受类型的值(NSObject) -> () -> ViewController。)
但是当给惰性变量提供类型注释时,例如
lazy var barButtonItem1: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action))
Run Code Online (Sandbox Code Playgroud)
源代码愉快地编译并被barButtonItem1.target设置为self.
我相信类型注释有助于编译。以上是我猜测您遇到的问题是由编译器错误引起的原因。
另请参阅:已报告与您遇到的问题类似的问题。两者都被总结为编译器错误。
| 归档时间: |
|
| 查看次数: |
455 次 |
| 最近记录: |