iOS lazy var UIBarButtonItem目标问题 [英] iOS lazy var UIBarButtonItem target issue

查看:142
本文介绍了iOS lazy var UIBarButtonItem目标问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用惰性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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆