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