I have a basic question. I'm working on a project with many delegate patterns, and would like reference on the best way about initializing them..
Here's some ideas with a test delegate I made:
It fails because I'm initilizing the delegate to self before super.init()
protocol MyClassDelegate {
func doSomething()
}
class MyClass {
var delegate: MyClassDelegate!
init(delegate: MyClassDelegate){
self.delegate = delegate
}
func myClassFuction(){
self.delegate.doSomething()
}
}
class ClassConformingToDelegate: NSObject, MyClassDelegate {
let myClass: MyClass
override init(){
myClass = MyClass(delegate: self) // Error because it's called before super.init
super.init()
}
func doSomething(){
//called from the delegate
}
}
It works, but then I risk having the delegate be nil.. Would I have to run a 'if delegate != nil' check each time I want to call a method? Is there a way around that? Is it a good practice to init the delegate this way?
protocol MyClassDelegate {
func doSomething()
}
class MyClass {
var delegate: MyClassDelegate!
init(){
}
func myClassFuction(){
self.delegate.doSomething() // might fail if delegate is nil
}
}
class ClassConformingToDelegate: NSObject, MyClassDelegate {
let myClass: MyClass
override init(){
myClass = MyClass()
super.init()
myClass.delegate = self // works because called after super.init
}
func doSomething(){
//called from the delegate
}
}
Those were just a couple ideas. I'm just trying to learn the best way of doing it. I'm open to all suggestions.
Thanks!!
Use lazy initialization to work around that issue.
protocol MyClassDelegate: class {
func doSomething()
}
class MyClass {
private(set) weak var delegate: MyClassDelegate?
func myClassFuction ( ) {
self.delegate?.doSomething()
}
init ( delegate: MyClassDelegate ) {
self.delegate = delegate
}
}
class ClassConformingToDelegate: NSObject, MyClassDelegate {
lazy private(set) var myClass: MyClass = {
return MyClass(delegate: self)
}()
func doSomething ( ) {
//called from the delegate
}
}
The variable myClass
, which has no public setter, will be initialized the first time it is accessed by ClassConformingToDelegate
itself or by some external code. If you want to make sure that it is always initialized when creating a new ClassConformingToDelegate
object (as its sole creation may have side effects, like registration to notifications and so on), just access it from init
:
override
init ( ) {
super.init()
_ = self.myClass
}
Option 2 looks better. However, in this case it would be advisable to use an optional as your delegate type. That way, you don't need to check "if delegate != nil" every time you want to perform a task with it. You can simply use optional chaining, which is designed specifically for such cases where you want to perform a task on an optional only if it contains a value.
protocol MyClassDelegate {
func doSomething()
}
class MyClass {
var delegate: MyClassDelegate?
init(){
}
func myClassFuction(){
self.delegate?.doSomething() // will do nothing if delegate is nil
}
}
class ClassConformingToDelegate: NSObject, MyClassDelegate {
let myClass: MyClass
override init(){
myClass = MyClass()
super.init()
myClass.delegate = self
}
func doSomething(){
//called from the delegate
}
}
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