【问题标题】:Cannot use instance member within property initializer不能在属性初始化器中使用实例成员
【发布时间】:2026-02-08 13:15:01
【问题描述】:

我写了一个自定义的UIView,我发现了一个奇怪的问题。我认为这与一个非常基本的概念有关,但我就是不明白,sigh.....

class ArrowView: UIView {

    override func draw(_ rect: CGRect) {

        let arrowPath = UIBezierPath.bezierPathWithArrowFromPoint(startPoint: CGPoint(x:bounds.size.width/2,y:bounds.size.height/3), endPoint: CGPoint(x:bounds.size.width/2, y:bounds.size.height/3*2), tailWidth: 8, headWidth: 24, headLength: 18)

        let fillColor = UIColor(red: 0.00, green: 0.59, blue: 1.0, alpha: 1.0)
        fillColor.setFill()
        arrowPath.fill()
    }
}

这段代码可以正常工作,但是如果我从覆盖绘制函数中抓取了这条线,它就不会编译。错误说我不能使用 bounds 属性。

let arrowPath = UIBezierPath.bezierPathWithArrowFromPoint(startPoint: CGPoint(x:bounds.size.width/2,y:bounds.size.height/3), endPoint: CGPoint(x:bounds.size.width/2, y:bounds.size.height/3*2), tailWidth: 8, headWidth: 24, headLength: 18)

不能在属性初始化器中使用实例成员“边界”;属性初始化器在“self”可用之前运行

我不明白为什么我不能在 func draw 之外使用这个边界

【问题讨论】:

标签: ios swift3


【解决方案1】:

因此,如果我们对错误消息进行解码,您就可以找出问题所在。它说property initializers run before self is available,所以我们需要调整我们正在做的事情,因为我们的属性取决于属于自己的边界。让我们尝试一个惰性变量。您不能在 let 中使用边界,因为在创建该属性时它不存在,因为它属于 self。所以在 init self 还没有完成。但是如果你使用惰性 var,那么 self 和它的属性边界就会在你需要的时候准备好。

lazy var arrowPath = UIBezierPath.bezierPathWithArrowFromPoint(startPoint: CGPoint(x: self.bounds.size.width/2,y: self.bounds.size.height/3), endPoint: CGPoint(x: self.bounds.size.width/2, y: self.bounds.size.height/3*2), tailWidth: 8, headWidth: 24, headLength: 18)

【讨论】:

  • 它如何影响 arrowPath 的行为?我的意思是在将 let 更改为 lazey var 后,该项目会发生什么?
  • lazy var 表示该属性在第一次访问之前为空。至关重要的是,这意味着 self.bounds 可用,因为在初始化 self 之前无法访问此属性。