如何设置对类成员的弱引用,例如回调方法?

时间:2014-07-11 22:19:08

标签: ios swift

在玩Swift的ARC机制时,我注意到你不能创建对非类成员的弱引用,否则你会得到编译错误“弱不能应用于非类型X”,所以如果我想将回调传递给另一个类,例如:

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()

在前面的例子中,我将“回调”方法传递给了B类,因此,如果我需要在发生某些事情时得到通知,B类可以调用它,它将在A类中执行,并且它完美地工作,唯一的问题是它从B创建了对A的强引用,并且当A被设置为n时它不会允许A被删除,因为B保持强引用,所以我知道如果我执行以下操作它会起作用:

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()

但是,有没有办法只对成员进行弱引用(在本例中为方法),而不是必须将引用传递给整个类?

问候!

1 个答案:

答案 0 :(得分:4)

不是仅仅将callback的引用传递给B的初始值设定项,而是创建一个使用对weak的{​​{1}}或unowned引用的闭包:

self

此外,您的代码中还有其他一些问题:

class A{
var b:B?
init(){
    b = B { [unowned self] in self.callback($0) }
}
...

不是惯用的快速;表达这一点的首选方式是

if b != nil{
    b!.somethingHappenedHenceCallback()
}

并且if let x = b { x.somethingHappenedHenceCallback() } 是不必要的,并且可能会给编译器错误;为if method != nil指定的类型不是可选的,因此它永远不会是method