The following class has a 'let
' property declared as implicitly unwrapped variable. This previously worked with 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) {
// ...
}
}
After updating to Xcode 6.3 (with Swift 1.2), the following compilation errors occur:
Property 'self.panGestureRecognizer' not initialized at super.init call
Immutable value 'self.panGestureRecognizer' may only be initialized once
Moving the following line before the super.init
call:
self.pandGestureRecognizer = UIPanGestureRecognizer(target: self, action: "panAction:")
gives the following error:
'self' is used before super.init call
The property 'panGestureRecognizer
' requires no mutation, therefore it has to be declared as constant 'let
'. Since it is a constant, it has to have an initial value upon declaration, or initialize it within the init
method. To initialize it, it requires to pass 'self
' in the 'target
' parameter.
Other thread suggested to declare it as implicitly unwrapped optional, and initialize it after the super.init
call. This previously worked until I updated to Xcode 6.3.
Does anybody know a proper implementation or a workaround for this case?
The Problem
The problem is your use of let
- optionals declared as let
aren't given a default value of nil
(var
is however). The following, introduced in Swift 1.2, wouldn't be valid otherwise since you wouldn't be able to give myOptional
a value after declaring it:
let myOptional: Int?
if myCondition {
myOptional = 1
} else {
myOptional = nil
}
Therefore, you're getting the error 'Property 'self.panGestureRecognizer' not initialized at super.init call' because before calling super.init(coder: aDecoder)
, because panGestureRecognizer
isn't nil
; it hasn't been initialised at all.
The Solutions:
1. Declare panGestureRecognizer
as a var
, meaning it will be given a default value of nil
, which you could then change after calling super.init(coder: aDecoder)
.
2. In my opinion, the better solution: don't use an implicitly unwrapped optional and declare panGestureRecognizer
with an initial value of UIPanGestureRecognizer()
. Then set the target after super.init
is called:
class SubView: UIView {
let panGestureRecognizer = UIPanGestureRecognizer()
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
panGestureRecognizer.addTarget(self, action: Selector("panAction:"))
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With