UIViewController变量初始化

时间:2015-01-03 17:46:20

标签: ios variables swift uiviewcontroller initialization

我正在研究swift语言,我对UIViewController中的变量初始化有疑问。在我的DiagramViewController我有一些变数:

class DiagramViewController: UIViewController {

    var type: Constants.DiagramType
    var filename: String
    var numberOfBars: Int
    var numberOfSection: Int
    var diagramName: String

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

Swift需要这些var的init值,我可以通过多种方式实现,但是我应该如何在这些方式之间进行选择?

我可以初始化变量“inline”:

class DiagramViewController: UIViewController {

    var type: Constants.DiagramType = Constants.DiagramType.HISTOGRAM
    var filename: String = "dd.txt"
    var numberOfBars: Int = 10
    var numberOfSection: Int = 5
    var diagramName: String = "Diagram"

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

我可以初始化覆盖构造函数的变量:

class DiagramViewController: UIViewController {

    var type: Constants.DiagramType
    var filename: String
    var numberOfBars: Int
    var numberOfSection: Int
    var diagramName: String

    required init(coder aDecoder: NSCoder) {
        type = Constants.DiagramType.HISTOGRAM
        filename = "dd.txt"
        numberOfBars = 10
        numberOfSection = 5
        diagramName = "Diagram"

        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

我可以将变量声明为Optional变量:

class DiagramViewController: UIViewController {

    var type: Constants.DiagramType?
    var filename: String?
    var numberOfBars: Int?
    var numberOfSection: Int?
    var diagramName: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        type = Constants.DiagramType.HISTOGRAM
        filename = "dd.txt"
        numberOfBars = 10
        numberOfSection = 5
        diagramName = "Diagram"

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

我可以初始化变量,将它们声明为Implicitly Unwrapped Optional

class DiagramViewController: UIViewController {

    var type: Constants.DiagramType!
    var filename: String!
    var numberOfBars: Int!
    var numberOfSection: Int!
    var diagramName: String!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        type = Constants.DiagramType.HISTOGRAM
        filename = "dd.txt"
        numberOfBars = 10
        numberOfSection = 5
        diagramName = "Diagram"

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

为什么选择方法而不是另一种?有关此问题的典型模式还是某种标准?也许其中一些解决方案比其他解决方案更清洁,甚至更高效。请帮我理解它们之间的区别。先感谢您。

2 个答案:

答案 0 :(得分:10)

这个问题可归纳为“我应该何时使用选项?”。关于这个问题有很多很棒的文章和文档,但我会尝试将我的经验与我阅读的文档和文章结合起来。

虽然Optionals在使用时具有非常特定的功能,但我想更多地将它们视为一种关于变量本身而不是声明功能的方式。当我读到:

var myVar:Class? = nil

这意味着,我们永远不应该预料到myVar被分配,而是我们应该始终预测这两个条件,第一个是myVar有一个值,而它没有。我假设这些东西是因为?可选项带来的功能。编译器不允许您在不解包的情况下使用myVar。因此,编译器建议(无论何时访问属性或函数)使用此语法:

myVar?.myProperty = something

由于?之前.这行代码将检查,以便在展开{{1}之前查看myVar是否为nil并执行代码行。因此,我们预测并处理了这两个条件。如果myVar为nil,那么这行代码基本上会被“忽略”,如果不是,则会被执行。

这与其他类型的可选myVar形成对比:

!

始终尝试展开myVar!.myProperty = something 。这行代码将导致异常,说明以下内容:“在展开值时意外发现nil。”。虽然myVar会无声地失败。

如果我们更改?的声明以使用myVar可选:

!

然后我们总是可以使用var myVar:Class! = nil 而不会遇到编译器错误,说我们需要在使用之前解包myVar。例如,与其他可选(myVar)不同,我们可以说:

?

这一行相当于:

myVar.myProperty = something

因此,如果myVar!.myProperty = something myVar,那么我们会崩溃该程序。

结论:

使用这些选项中的任何一个(或根本不使用可选项),我们告诉用户nil关于myVar的事情,因为该语言会强制或不强制您使用处理myVar

myVar可选?

如果我使用var myVar:Class? = nil可选,我们实际上是强迫用户始终检查?

nil可选!

如果我们使用var myVar:Class! = nil,那么如果!为零,则出现问题,我们应该使程序崩溃,但是,用户仍然可以选择处理myVar案例如果用户是应该分配nil的用户,则特别有用。一个很好的用例是网络请求。

没有可选的myVar

根本不使用可选项(显然)变量总是,我们不需要担心它是var myVar = Class()

答案 1 :(得分:1)

我现在的处理方式是由一位开发人员教给我的,涉及到在知道总会设置一个值的情况下使用Xcode的处理方式:

对于出口,您将看到这样写的实例变量(作为出口):

@IBOutlet weak var twoPlayerButton: UIButton!

因此,如果您可以在实例变量声明行中实例化该类,那么我将:

private var myClass: MyClass = MyClass()

如果您无法在实例变量行中设置MyClass()(例如,因为其构造函数需要传入其他变量),那么我将设置实例变量,类似于xcode处理Outlets的方式:

private var myClass: MyClass!

然后在viewDidLoad()方法中实例化它

但是,如果我没有尽早设置该值和/或可能将其设置回nil,那么我将其声明为可选值,并要求在我的类中编辑代码的任何人都必须对其进行适当的包装。

相关问题