Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 为什么是伊巴布顿主义';在使用init初始化时,是否将目标设置为nil(barButtonSystemItem、目标、操作)?_Ios_Swift_Initialization_Uibarbuttonitem - Fatal编程技术网

Ios 为什么是伊巴布顿主义';在使用init初始化时,是否将目标设置为nil(barButtonSystemItem、目标、操作)?

Ios 为什么是伊巴布顿主义';在使用init初始化时,是否将目标设置为nil(barButtonSystemItem、目标、操作)?,ios,swift,initialization,uibarbuttonitem,Ios,Swift,Initialization,Uibarbuttonitem,这个初始值设定项 convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem, target: Any?, action: Selector?) 接受一个目标,然后在返回部分解释它实际上被设置为nil。他们为什么这么做 我的意思是,他们真的这么做是因为这件事让我发疯,我不得不这样写代码: class GameViewController: UIViewController {

这个初始值设定项

convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem, 
      target: Any?, 
      action: Selector?)
接受一个目标,然后在返回部分解释它实际上被设置为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

        . . . 
}
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))
    }
}
因为否则不会触发该操作。为什么他们认为接受一个参数并故意忽略它是个好主意


编辑:我使用nil self初始化对象是我的错(如下面的答案所指出的)。然而,这个问题仍然存在。因为他们为什么说目标设置为nil而实际上不是呢?

目标为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

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

目标为零,因为在控制器初始化之前设置了目标。 您应该使用如下内容:

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

        . . . 
}
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(代码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)
)
我不知道为什么会发生这种情况,但确实如此。

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

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

完全正确。我没想到!但有一个类似的问题要问。请看编辑。完全正确。我没想到!但有一个类似的问题要问。我想,他们说的目标是:有吗?,-可选。为了安全使用,否则如果对象解除分配,应用程序将崩溃。我指的是一条新初始化的包含指定系统项的语句
。项目的目标为零。
目标和选择器都是可选的。他们说唯一的目标是零。也许,这是基于访问级别。因为我可以从UIBarButtonItem返回的对象中获取目标,但是我无法获取此对象的操作选择器(私有访问)。我想,他们说目标:Any?,-可选。为了安全使用,否则如果对象解除分配,应用程序将崩溃。我指的是一条新初始化的包含指定系统项的语句
。项目的目标为零。
目标和选择器都是可选的。他们说唯一的目标是零。也许,这是基于访问级别。因为我可以从UIBarButtonItem返回的对象中获取目标,但无法获取此对象的操作选择器(私有访问)。