iOS lazy var UIBarButtonItem目标问题

问题描述:

我在使用lazy var初始化时无意识地发现了这个UIBarButtonItem目标问题。iOS 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 writing时遇到了这个问题,然后我发现barButtonItem1的操作永远不会被调用,最后问题是barButtonItem1.target为零。

我不知道为什么会发生这种情况,但我很确定这是一个错误。 有没有人知道这件事?如果你能解释它,我将非常感激。

+1

我不认为你正在做的'barButtonItem1'正确。首先'lazy var'必须用数据类型声明。其次,你只是将它的值设置为常规变量。请阅读:https://www.hackingwithswift。COM /例子代码/语言/什么,是懒惰变量 – thedp

+0

barButtonItem1的声明应该是正确的,按[链接](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language /Properties.html)。 – user5685969

+1

根据[link](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html),barButtonItem1的声明应该是正确的。不过,我尝试了你所说的为barButtonItem1添加数据类型声明,现在它表现良好。我仍然不知道是什么原因造成的。 – user5685969

下面的解释是我的猜测。不幸的是,我没有足够的声望发表评论,所以让我给你一个答案。

我的猜测:这是一个编译器错误。


首先,我制作了一个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) 
    } 
} 

然后我试图用下面的代码来初始化懒惰存储的变量。

class ViewController: UIViewController { 

    lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action)) 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     print(barButtonItem1.target) 
    } 
    func action() { } 
} 

然后编译引发错误,并说

无法将类型的价值 '(NSObject的) - >() - >视图控制器' 来 预期的参数类型“的UIViewController?

这表明编译器无法确定selfViewController。 (由UIKit提供的初始值设定将编译,因为第二个参数为Any?它接受(NSObject) ->() -> ViewController类型的值。)

但是,当给定类型的注释到像

lazy var barButtonItem1: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action)) 

源代码中的懒惰可变愉快地编译和barButtonItem1.target被设置为self

我相信类型注释有助于编译。以上是我猜你遇到的问题是由编译器错误引起的原因。


参见:类似于你所面临的问题据报道,有问题。它们都是编译器错误。

Swift lazy instantiating using self

Type inference when using lazy instantiation

+0

谢谢!所以这真的是一个编译器错误,希望苹果能尽快修复它。现在,我们只需添加类型注释。 – user5685969