iOS lazy var UIBarButtonItem目标问题 [英] iOS lazy var UIBarButtonItem target issue
问题描述
我在使用惰性var初始化时无意识地发现了这个UIBarButtonItem目标问题。
I found this UIBarButtonItem target issue unconsciously when using lazy var initialization.
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为self,这看起来很疯狂!
当我使用barButtonItem1的懒惰var写时我得到了这个问题,然后我发现barButtonItem1的动作永远不会被调用,最后问题是barButtonItem1.target是nil。
The printed results showed that barButtonItem1.target was nil, and barButtonItem2.target was self, which seems crazy! I got this issue when i use barButtonItem1's lazy var writing, and then i found that barButtonItem1's action can never be called, and finally the issue was barButtonItem1.target was nil.
我不知道为什么会这样,但我很确定这是一个错误。
有谁知道这件事?如果你能解释一下,我将非常感激。
I don't know why this happens, however i'm pretty sure this is a bug. Does anyone know something about this? I will really appreciate it if you can explain about it.
推荐答案
以下说明是我的猜测。不幸的是,我没有足够的声誉发表评论,所以让我给你一个答案。
Explanation below is my guess. And unfortunately, I don't have enough reputation to give a comment so let me give you an answer.
我的猜测:这是一个编译错误。
My guess: this is a compiler bug.
首先,我精心设计了一个UIBarButtonItem的小扩展。 (第二个参数不是任何?
但是 UIViewController?
)
First, I crafted a small extension of UIBarButtonItem. (second parameter is not of 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)
}
}
然后我尝试使用下面的代码初始化延迟存储的变量。
Then I tried to initialize the lazy stored variable with the code below.
class ViewController: UIViewController {
lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action))
override func viewDidLoad() {
super.viewDidLoad()
print(barButtonItem1.target)
}
func action() { }
}
然后编译器引发了错误d say
Then compiler raised error and say
无法将类型'(NSObject) - >() - > ViewController'的值转换为
预期参数类型' UIViewController?'
Cannot convert value of type '(NSObject) -> () -> ViewController' to expected argument type 'UIViewController?'
这表明编译器未能确定 self
是的ViewController
。 (UIKit提供的初始化程序会编译,因为第二个参数是 Any?
,它接受类型的值(NSObject) - >() - > ; ViewController
。)
which suggests that compiler failed to determine that self
is of ViewController
. (The initializer provided by UIKit would compile because the second parameter is of Any?
which accepts value of type (NSObject) -> () -> ViewController
.)
但是给lazy变量赋予类型注释,比如
But when give type annotation to the lazy variable like
lazy var barButtonItem1: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action))
快乐编译的源代码和 barButtonItem1.target
设置为 self
。
source code happily compiled and barButtonItem1.target
was set to self
.
我相信类型注释有助于编译。以上是我猜您遇到的问题是由编译器错误引起的原因。
I believe the type annotation helped compile. Above is the reason I guess the issue you faced is caused by a compiler bug.
另请参阅:有报道的问题类似于您遇到的问题。它们都归结为编译器错误。
See also: there are reported problems similar to the issue you faced. Both of them are concluded as a compiler bug.
这篇关于iOS lazy var UIBarButtonItem目标问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!