为什么在使用init初始化时将UIBarButtonItem的目标设置为nil(barButtonSystemItem,target,action)?

时间:2016-10-31 09:30:24

标签: ios swift initialization uibarbuttonitem

此初始化程序

convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem, 
      target: Any?, 
      action: Selector?)

according to the documentation接受目标,然后在返回部分中,他们解释说它实际设置为 nil 。为什么他们这样做?

我的意思是他们实际上是这样做的,因为这是让我疯狂的事情,我不得不写这样的代码:

class GameViewController: UIViewController {


    let pauseItem = UIBarButtonItem(barButtonSystemItem: .pause, target: self, action: #selector(GameViewController.pauseButtonTouchUp))
    let playItem = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(GameViewController.pauseButtonTouchUp))



    override func viewDidLoad() {
        super.viewDidLoad()

        self.pauseItem.target = self
        self.playItem.target = self

        . . . 
}

因为否则不会触发动作。为什么他们认为接受参数并故意忽略它是个好主意?

编辑:我使用nil-self来初始化对象是我的错(正如下面的答案所指出的那样)。但问题仍然存在。因为他们为什么说当目标设置为 nil 时实际上不是?

2 个答案:

答案 0 :(得分:2)

目标为nil,因为您在控制器init之前设置了目标。 你应该使用这样的东西:

class GameViewController: UIViewController {
    var pauseItem: UIBarButtonItem? = nil
    var playItem: UIBarButtonItem? = nil

    override func viewDidLoad() {
        super.viewDidLoad()

        playItem = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(GameViewController.pauseButtonTouchUp))
        pauseItem = UIBarButtonItem(barButtonSystemItem: .pause, target: self, action: #selector(GameViewController.pauseButtonTouchUp))
    }
}

答案 1 :(得分:0)

Swift 3(Xcode 8.3.3)

在Swift 3中,您可以通过将属性声明为lazy var而不是let来解决此问题,但是您还必须明确属性的数据类型,而不是依赖于推断类型因为否则target将再次设置为nil,因为编译器有些怪癖。

This is required ----------+
                           |
                           v
lazy var pauseItem: UIBarButtonItem = UIBarButtonItem(
    barButtonSystemItem: .pause, 
    target: self, 
    action: #selector(GameViewController.pauseButtonTouchUp)
)

我不知道为什么会这样,但事实确实如此。