Let us suppose we have a protocol
protocol MyProtocol {
fun someFunc()
}
class AClass {
var delegate: MyProtocol?
}
AClass doesn't care if the delegate is a class or struct. What I want is sometimes the delegate can be a class and sometimes it can be assigned to a struct.
My question is if I should make the delegate to be "weak".
If so, I have to make MyProtocol be a "class Protocol" so that the delegate has to be a class only. If not, when I assign the delegate to class, how can I avoid retain cycle?
Thanks for any hint!
should make the delegate to be "weak"
The answer is that if MyProtocol
is not restricted to classes, you cannot make it weak, the compiler won't let you.
The reason for the above is that struct
s are value types. There isn't a reference that can be strong or weak, because logically the entire struct is copied in when you assign the delegate.
how can I avoid retain cycle?
This means that you have got to be careful that your delegate contains no strong references back to the instance of the class. So, for instance
struct ConcreteDelegate: MyProtocol
{
fun someFunc() {}
var instance: AClass
init()
{
instance = AClass()
instance.delegate = self
}
}
Causes a reference cycle. It can be broken by declaring instance
as
weak var instance: AClass!
Alternatively, and a better solution (IMO), your protocol functions can pass the instance as a parameter so the delegate never needs to store a reference to the instance.
protocol MyProtocol {
func someFunc(caller: AClass)
}
You'll see the above approach adopted in Cocoa in lots of places, for example with the table view data source protocol.