【问题标题】:swift global constants: cannot use another constant for initialization快速全局常量:不能使用另一个常量进行初始化
【发布时间】:2014-07-09 13:06:32
【问题描述】:

这是我想要做的:

class ViewController: UIViewController {
let screenRect: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenRect.width;
let screenHeight = screenRect.height;
let screenX = screenRect.origin.x
let screenY = screenRect.origin.y
override func viewDidLoad() {
...and so on

Swift 允许我声明screenRect

但是,它不允许我使用它来声明任何其他常量。它向我显示了错误:'ViewController.Type' does not have a member named 'screenRect'

我如何定义这些常量,为什么 swift 不允许我使用另一个常量来定义它们。

【问题讨论】:

    标签: ios swift constants global


    【解决方案1】:

    常量不知道其他全局常量,因为此时它们尚未初始化。你可以做的是使用计算属性:

    class ViewController: UIViewController {
      var screenRect: CGRect { return UIScreen.mainScreen().bounds }
      var screenWidth: CGFloat { return self.screenRect.origin.x }
    }
    

    由于它的性质,这只适用于 vars。这应该根据用例来考虑。如果您必须经常调用它,就性能而言,这可能不是最明智的方法。

    【讨论】:

      【解决方案2】:

      在初始化过程完成之前无法访问self,因此会报错。

      【讨论】:

        【解决方案3】:

        可能发生的情况是,在实例化和初始化期间,不能保证属性的初始化顺序与您在代码中定义它们的顺序相同,因此您无法使用从另一个属性检索到的值来初始化属性。

        我的建议是在init() 方法中移动属性初始化。

        附录 1:正如@Yatheesha 所建议的那样,说self 不可用是正确的直到所有属性都已初始化 - 请参阅“两阶段初始化" swift 书中的段落,在“初始化”下

        在这一行(以及它之后的行):

        let screenWidth = screenRect.width;
        

        您正在隐式使用self

        所以正确的方法是使用init()如下:

        let screenRect: CGRect
        let screenWidth: NSNumber
        let screenHeight: NSNumber
        let screenX: NSNumber
        let screenY: NSNumber
        
        init(coder aDecoder: NSCoder!) {
            let bounds = UIScreen.mainScreen().bounds
            screenRect = bounds
            screenWidth = bounds.width
            screenHeight = bounds.height
            screenX = bounds.origin.x
            screenY = bounds.origin.y
        
            super.init(coder:aDecoder)
        }
        

        当然,如果有多个指定的init(),您必须在每个上复制该代码。在这种情况下,如果您希望避免代码重复,最好使用 @Andy 的方法,使用计算属性。

        附录 2

        另一种明显的方式(可能也是最好的方式)是完全避免使用self

        let screenRect: CGRect = UIScreen.mainScreen().bounds
        let screenWidth = UIScreen.mainScreen().bounds.width;
        let screenHeight = UIScreen.mainScreen().bounds.height;
        let screenX = UIScreen.mainScreen().bounds.origin.x
        let screenY = UIScreen.mainScreen().bounds.origin.y
        

        【讨论】:

        • swift 似乎也不允许常量由文字常量定义,例如:let secondsPerMinute: Int = 60;让 minutesPerHour: Int = 60;让 secondsPerHour: Int = secondsPerMinute * minutesPerHour 会失败
        • @rockhammer 我在操场上尝试了该代码,它可以工作
        • 我没有在操场上尝试。 Xcode 在看到它时停止编译,无论如何对我来说
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多