swift global constants: cannot use another constant for initialization

后端 未结 3 934
时光说笑
时光说笑 2021-01-14 20:10

Here is what I am trying to do:

class ViewController: UIViewController {
let screenRect: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenRect.w         


        
相关标签:
3条回答
  • 2021-01-14 20:18

    Its not possible to access self before initialisation process gets completed, therefore its giving error.

    0 讨论(0)
  • 2021-01-14 20:40

    What probably happens is that during instantiation and initialization it's not guaranteed that properties are initialized in the same order as you have defined them in the code, so you cannot initialize a property with a value retrieved from another property.

    My suggestion is to move the property initializations in the init() method.

    Addendum 1: as suggested by @Yatheesha, it's correct to say that self is not available until all properties have been initialized - see "Two-Phase Initialization" paragraph in the swift book, under "Initialization"

    In this line (as well as in the ones after it):

    let screenWidth = screenRect.width;
    

    you are implicitly using self.

    So the correct way is to use init() as follows:

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

    Of course if there is more than one designated init(), you have to replicate that code on each. In that case it might be better to use @Andy's approach, using computed properties, if you prefer to avoid code duplication.

    Addendum 2

    Another obvious way (and probably the best one) is to avoid using self at all:

    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
    
    0 讨论(0)
  • 2021-01-14 20:41

    The consts do not know about the other global consts because they are not initialized at this point. What you could do though is to use computed properties:

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

    This only works with vars, due to the nature of it. This should be considered depending on the use case. If you have to call it often, it might not be the wisest way in regards to performance.

    0 讨论(0)
提交回复
热议问题