为什么NSHashTable会保留指针的引用?

4
我需要一个弱引用的对象NSHashTable,如果其中一个对象变成nil,我希望NSHashTable自动从列表中删除该对象。
以下是代码:
import Foundation

class Router: NSObject {
  let listeners: NSHashTable<Listener> = NSHashTable.weakObjects()
}



class Listener: NSObject {
}




let router = Router()
var listener1: Listener? = Listener()

router.listeners.add(listener1)

print("before", router.listeners.count)

listener1 = nil

print("after", router.listeners.count)

日志如下:

before 1
after 1

我是否理解弱引用哈希表的主要目的?我的理解是,当对象失去所有强引用时,也会从哈希表中删除。这样做的原因是什么呢?

1个回答

2

你的理解是正确的,但是count getter有些混乱。在playgrounds中查看以下内容,您将看到一旦释放强引用,即使对象在NSHashTable中,也会调用deinit。然而,count方法似乎存在某种缓存问题。您可以使用allObjects.count而不是count方法,它返回正确的值,但是无论如何对象都会被正确释放。之后的分派是为了确保对象在下一个运行循环“帧”中被清除。

import UIKit
import XCPlayground

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

class Listener: NSObject {
    deinit {
        print("deinit")
    }
}

let listeners = NSHashTable<Listener>(options: .weakMemory)

var listener: Listener? = Listener()

listeners.add(listener)

print("count:\(listeners.count) allObjects.count\(listeners.allObjects.count)")
listener = nil

DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
    print("count:\(listeners.count) allObjects.count:\(listeners.allObjects.count)")
}

输出:

count:1 allObjects.count:1
deinit
count:1 allObjects.count:0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接