为什么在使用 init(barButtonSystemItem, target, action) 初始化时 UIBarButtonItem 的目标设置为 nil?
Why is UIBarButtonItem's target set to nil when initializing with init(barButtonSystemItem, target, action)?
这个初始化器
convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem,
target: Any?,
action: Selector?)
according to the documentation 接受一个 target 然后在 return 部分他们解释说它实际上设置为 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 而实际上不是?
target nil,因为你在控制器初始化之前设置了目标。
你应该使用这样的东西:
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))
}
}
Swift 3 (Xcode 8.3.3)
在 Swift 3 中,您可以通过将属性声明为 lazy var
而不是 let
来解决此问题,但是您还必须明确 [= 的数据类型24=] 而不是依赖于推断类型,否则 target
将由于编译器的某些怪癖再次设置为 nil
。
This is required ----------+
|
v
lazy var pauseItem: UIBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .pause,
target: self,
action: #selector(GameViewController.pauseButtonTouchUp)
)
我不知道为什么会这样,但确实如此。
这个初始化器
convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem,
target: Any?,
action: Selector?)
according to the documentation 接受一个 target 然后在 return 部分他们解释说它实际上设置为 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 而实际上不是?
target nil,因为你在控制器初始化之前设置了目标。 你应该使用这样的东西:
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))
}
}
Swift 3 (Xcode 8.3.3)
在 Swift 3 中,您可以通过将属性声明为 lazy var
而不是 let
来解决此问题,但是您还必须明确 [= 的数据类型24=] 而不是依赖于推断类型,否则 target
将由于编译器的某些怪癖再次设置为 nil
。
This is required ----------+
|
v
lazy var pauseItem: UIBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .pause,
target: self,
action: #selector(GameViewController.pauseButtonTouchUp)
)
我不知道为什么会这样,但确实如此。