在Swift 1.2的init方法中将自身作为parameter passing

下面的类有一个“ let ”属性声明为隐式解包variables。 以前在Xcode 6.2上工作过:

 class SubView: UIView { let pandGestureRecognizer: UIPanGestureRecognizer! required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.pandGestureRecognizer = UIPanGestureRecognizer(target: self, action: "panAction:") } func panAction(gesture: UIPanGestureRecognizer) { // ... } } 

更新到Xcode 6.3(使用Swift 1.2)后,发生以下编译错误:

 Property 'self.panGestureRecognizer' not initialized at super.init call Immutable value 'self.panGestureRecognizer' may only be initialized once 

super.init调用之前移动以下行:

 self.pandGestureRecognizer = UIPanGestureRecognizer(target: self, action: "panAction:") 

给出以下错误:

 'self' is used before super.init call 

属性' panGestureRecognizer '不需要突变,因此必须声明为常量' let '。 由于它是一个常量,它必须在声明时具有初始值,或者在init方法中初始化它。 要初始化它,它需要在' target '参数中传递' self '。

其他线程build议将其声明为隐式解包可选,并在super.init调用之后对其进行初始化。 这之前工作,直到我更新到Xcode 6.3。

有没有人知道这种情况下的正确实施或解决方法?

问题

问题是你使用let – optionals声明为let没有被赋予一个默认值nilvar是然而)。 在Swift 1.2中引入的以下内容将是无效的,因为在声明之后,您将无法给myOptional一个值:

 let myOptional: Int? if myCondition { myOptional = 1 } else { myOptional = nil } 

因此,在调用super.init(coder: aDecoder)之前,你得到的错误是'Property'self.panGestureRecognizer'没有在super.init调用中初始化',因为panGestureRecognizer不是nil ; 它还没有被初始化。

解决scheme:

1.将 panGestureRecognizer声明为var ,这意味着它将被赋予一个默认值nil ,然后你可以在调用super.init(coder: aDecoder)之后改变它。

2.在我看来,更好的解决scheme:不要使用隐式解包的可选项,并声明与UIPanGestureRecognizer()的初始值UIPanGestureRecognizer() 。 然后在调用super.init之后设置目​​标:

 class SubView: UIView { let panGestureRecognizer = UIPanGestureRecognizer() required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) panGestureRecognizer.addTarget(self, action: Selector("panAction:")) } } 

除非该类被初始化,否则不能使用self 。 如果你想用self的属性初始化,它必须是lazy 。 但lazy不支持let ,只是var

那是因为:

您必须始终将lazy属性声明为variables(使用var关键字),因为在实例初始化完成之前,可能不会检索其初始值。 在初始化完成之前,常量属性必须始终有一个值,因此不能声明为惰性。

这是一种妥协,如果你可以与私人定居者生活,你可以这样做:

 class SubView: UIView { private(set) lazy var panGestureRecognizer: UIPanGestureRecognizer = { [unowned self] in UIPanGestureRecognizer(target: self, action: "panAction:") }() required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } func panAction(gesture: UIPanGestureRecognizer) { } } 

或者使用UIPanGestureRecognizer()初始化panGestureRecognizer并稍后添加目标。

解决这个特定情况的方法是:

 class SubView: UIView { let pandGestureRecognizer: UIPanGestureRecognizer required init(coder aDecoder: NSCoder) { self.pandGestureRecognizer = UIPanGestureRecognizer() super.init(coder: aDecoder) self.pandGestureRecognizer.addTarget(self, action: "panAction:") } func panAction(gesture: UIPanGestureRecognizer) { // ... } 

}