gpt4 book ai didi

ios - 迭代 NSMapTable 中的键永远保留弱值

转载 作者:搜寻专家 更新时间:2023-11-01 06:52:14 25 4
gpt4 key购买 nike

我正在尝试使用 NSMapTable 弱存储一些对象实例,由字符串索引。

(我的用例是存储一些有关远程服务器的缓存元数据,并让每个事件客户端共享该元数据。当没有客户端连接到该特定服务器时,应从内存中删除元数据。)

这一切都很好,只要我从不重复键。看起来,如果我迭代了一个特定的键,该键的值将永远不会被释放。

我已经设法将其简化为显示问题的一小段代码:

import Foundation

class Foobar {
let id: String
init(_ id: String) { print("init \(id)"); self.id = id }
deinit { print("deinit \(id)") }
}

let map = NSMapTable<NSString, Foobar>(keyOptions: .strongMemory, valueOptions: .weakMemory)

func addSome() {
let a = Foobar("a")
let b = Foobar("b")
let c = Foobar("c")

map.setObject(a, forKey: "a")
map.setObject(b, forKey: "b")
map.setObject(c, forKey: "c")

let e = map.keyEnumerator()
print("nextObject: \(e.nextObject() ?? "nil")")
print("nextObject: \(e.nextObject() ?? "nil")")
print("nextObject: \(e.nextObject() ?? "nil")")
print("nextObject: \(e.nextObject() ?? "nil")")
}

addSome()

print(map.object(forKey: "a") ?? "nil")
print(map.object(forKey: "b") ?? "nil")
print(map.object(forKey: "c") ?? "nil")

如果我注释掉一个或多个 e.nextObject() 调用,相应键的值将被正确释放,并且 map.object(forKey:) 将正确返回 nil

我是否必须在以某种方式完成枚举器后手动清理它?

最佳答案

显然, map 枚举器返回“自动释放”对象——当当前自动释放池的范围离开时,这些对象将被释放。

在 iOS 或 macOS 应用程序中,当程序控制返回主事件循环时会自动发生。在任何情况下,您都可以使用本地 autorelease pool

autoreleasepool {
let e = map.keyEnumerator()
print("nextObject: \(e.nextObject() ?? "nil")")
print("nextObject: \(e.nextObject() ?? "nil")")
print("nextObject: \(e.nextObject() ?? "nil")")
print("nextObject: \(e.nextObject() ?? "nil")")
}

在枚举后立即释放对象。

备注: NSEnumerator 是一个Sequence,因此您可以用for循环枚举它:

autoreleasepool {
let e = map.keyEnumerator()
for case let key as String in e {
print(key)
}
}

关于ios - 迭代 NSMapTable 中的键永远保留弱值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56405398/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com