Pass self as argument within init method in Swift 1.2
You can't use self
unless the class is initialized. And if you would like to use self
for property initialization, it must be lazy
. But lazy
is not supported for let
, just var
.
That's because:
You must always declare a lazy property as a variable (with the var keyword), because its initial value might not be retrieved until after instance initialization completes. Constant properties must always have a value before initialization completes, and therefore cannot be declared as lazy.
It's kind of compromise and if you can live with private setter, you can do this:
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) {
}
}
Or initialize panGestureRecognizer
with just UIPanGestureRecognizer()
and add target later.
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:"))
}
}