Reputation: 13705
While playing with Swift's ARC mechanism, I noticed that you cannot create a weak reference to a non-class member or you would get the compiling error "weak cannot be applied to non-class type X", so if I would like to pass a callback to another class for example:
class A{
var b:B?
init(){
b = B(callback)
}
func callback(name:String){
print("name: \(name)")
}
func trigger(){
if b != nil{
b!.somethingHappenedHenceCallback()
}
}
}
class B{
var method:((name:String)->Void)
init(method:(name:String)->Void){
self.method = method
}
func somethingHappenedHenceCallback(){
if method != nil{
method(name: "From class B")
}
}
}
var a:A = A()
a.trigger()
In the previous example I'm passing the "callback" method to the class B, so, if I need to be notified when something happens, the class B can call it and it will be executed in class A, and it works perfectly, the only problem is that it creates a strong reference to A from B, and it will not allow A to be deinited when A is set to nil because B is keeping a strong reference, so I know that if I do the following it will work:
class A{
var b:B?
init(){
b = B(a:self)
}
func callback(name:String){
print("name: \(name)")
}
func trigger(){
if b != nil{
b!.somethingHappenedHenceCallback()
}
}
}
class B{
var a:A?
init(a:A){
self.a = a
}
func somethingHappenedHenceCallback(){
if a != nil{
a!.callback("From class BB")
}
}
}
var a:A = A()
a.trigger()
However, is there a way to make a weak reference to the member only(in this case the method) instead of having to pass a reference to the whole class?
Regards!
Upvotes: 1
Views: 2776
Reputation: 4170
Rather than just passing a reference to callback
to the initializer for B
, create a closure that uses a weak
or unowned
reference to self
:
class A{
var b:B?
init(){
b = B { [unowned self] in self.callback($0) }
}
...
Also, you have a couple other issues in your code:
if b != nil{
b!.somethingHappenedHenceCallback()
}
is not idiomatic swift; the preferred way to express this is
if let x = b {
x.somethingHappenedHenceCallback()
}
And if method != nil
is unnecessary, and could possibly give a compiler error; the type given for method
is not an optional and therefore it can never be nil
Upvotes: 4