BR41N-FCK BR41N-FCK - 1 month ago 7
Swift Question

Why is UIBarButtonItem's target set to nil when initializing with init(barButtonSystemItem, target, action)?

This initializer

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


according to the documentation accepts a target and then in the return section they explain that it is actually set to nil. Why do they do it?

And I mean they actually do it because it was the thing that drove me crazy and I had to write code like this:

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

. . .
}


Because otherwise the action would not be triggered. Why did they decide it was a good idea to accept a parameter and deliberately ignore it?

EDIT: It was my fault (as pointed out in the answer below) that I used a nil-self to initialize the object. However, the question kind of still holds. Because why do they state that target is set to nil when it actually isn't?

Answer

target nil, because you are set the target before controller init. You should use something like this:

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))
    }
}