swift global constants: cannot use another constant for initialization

南楼画角 提交于 2019-12-01 10:59:53

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.

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

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!