快速授权 - 何时使用弱引用,为什么'委托'是零?

时间:2016-01-05 12:35:50

标签: swift protocols delegation

这是我的代码:

protocol Delegate: NSObjectProtocol {}

class A: NSObject {
    weak var delegate: Delegate!
    override init() {
        super.init()
    }
    func start() {
        //synchronous------- print A: false
        print("A:", delegate == nil)

        //asynchronous------- print B: true  Why is 'true'? How can do that not be released?
        let time: NSTimeInterval = 1
        let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(time * Double(NSEC_PER_SEC)))
        dispatch_after(delay, dispatch_get_main_queue()) {
            print("B:", self.delegate == nil)
        }
    }
}

class B: NSObject, Delegate {
    override init() {
        super.init()
        let a = A()
        a.delegate = self
        a.start()
    }
}

我搜索了有关堆栈溢出的其他问题,但我找不到可以帮助我完全理解这种情况的东西。

1 个答案:

答案 0 :(得分:2)

在A类中,您将委托定义为。这意味着如果没有其他对象引用委托对象(在您的情况下为B类的实例),则可以释放此实例。

在运行开始时,B类的实例被某个对象引用。在此B类中,您创建了A类实例,并将B类实例指定为其委托。 当您打印委托值时,它不是零。

后来,除了A类实例之外,其他对象不再引用类B的实例。由于A类实例将其称为,因此其引用不计数,实例A从内存中释放。这就是为什么当你在一秒后打印委托值时它是零。

为什么要使用弱? 如果你没有使用weak,那么A类实例将保存对B类实例的引用,而B类实例将保存对A类实例的引用。这样两个实例的引用计数将大于0,并且它们都不会被释放!这将导致内存泄漏。你想要的是,如果没有其他对象引用B类对象,它将从内存中释放出来,因此A类对象也可以被释放。