我试图弄清楚NSMapTable是如何工作的,所以我在操场上尝试使用以下代码:
class Person {
var name: String
init(name: String ) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
var hobyePerson : NSMapTable? = NSMapTable<Person, NSMutableString>
(keyOptions: .weakMemory, valueOptions: .weakMemory)
var rob : Person? = Person(name: "Rob Appleseed") // print : Rob Appleseed is being initialized
hobyePerson?.setObject("golf", forKey: rob)
hobyePerson?.count // return : 1
rob = nil // print : Rob Appleseed is being deinitialized
hobyePerson?.count // return : 1 (WHY ???!!!!)
正如在文档中所写的:“键和/或值可选地”持有“弱”,以便在回收其中一个对象时删除条目。
为什么即使我初始化对象,使它在取消分配rob时对键值对有一个弱引用,我仍然在hobyePerson中有一个元素?
发布于 2017-10-30 20:09:46
当您不关心何时释放键/值时,NSMapTable
的weak
行为选项工作得最好,但是您确实关心的是,键/值没有被强烈保留,并且在感兴趣的对象成为nil
之后会在某个时候释放。
为什么会这样呢?
作为一个基础类,NSMapTable
的作者必须平衡特性和性能。
因此,作为性能的“优化”,他们选择成为nil
的弱引用对象不会立即从映射表中删除.!相反,“稍后”就会发生这种情况,因为它可以有效地完成--例如,当映射表内部调整大小时,等等。
正如@路克在他的回答中所提到的,更多细节请看这篇关于NSMapTable
行为实验的优秀文章:
http://cocoamine.net/blog/2013/12/13/nsmaptable-and-zeroing-weak-references/
发布于 2017-10-27 20:05:36
发布于 2022-06-29 19:13:49
它对我不起作用,所以我实现了这样简单的弱映射。会改善它的加班,但现在起作用了:
import Foundation
private struct WeakValue<Value:AnyObject> {
weak var value: Value?
}
public class CSWeakValueDictionary<Key:AnyObject, Value:AnyObject> {
private let dictionary = NSMutableDictionary()
public subscript(source: Key) -> Value? {
get {
let value = (dictionary["\(source)"] as? WeakValue<Value>)?.value
if value == nil { dictionary.removeObject(forKey: "\(source)") }
return value
}
set { dictionary["\(source)"] = WeakValue(value: newValue) }
}
}
https://stackoverflow.com/questions/46982265
复制相似问题