4
我正在实现一个WeakSet
,它将其元素弱地包装在WeakWrapper
中,以便不增加其保留数。实现在WeakSet中跳过零元素的自定义迭代器
我的问题是,我该如何创建一个迭代器,以便我可以遍历那些跳过那些已被释放的元素(即nil
)。
请注意,我试图优化迭代;如果插入/删除相对较慢,那么可以,但是设置迭代器应该没有/没有性能成本。
这是我的WeakSet
它的基本形式。我可以打电话clean()
删除WeakWrapper
(胡)的对象已被释放:
struct WeakSet<T> where T: AnyObject & Hashable {
private var set: Set<WeakWrapper<T>> = []
mutating func insert(_ elem: T) {
self.set.insert(WeakWrapper<T>(elem))
}
mutating func remove(_ elem: T) {
self.set.remove(WeakWrapper<T>(elem))
}
mutating func clean() {
for elem in set {
if elem.obj == nil {
self.set.remove(elem)
}
}
}
}
fileprivate class WeakWrapper<T>: Hashable where T: AnyObject {
weak var obj: T?
let hashValue: Int
init(_ obj: T) {
self.obj = obj
self.hashValue = ObjectIdentifier(obj).hashValue
}
static func ==(lhs: WeakWrapper, rhs: WeakWrapper) -> Bool {
return lhs.hashValue == rhs.hashValue
}
}
我希望能够做这样的事情,如果生成的元素T
类型的底层非空的元素,而不是包裹元素:
class MyObject: NSObject {
func doSomething() { }
}
var weakSet = WeakSet<MyObject>()
for myObject in weakSet {
myObject.doSomething()
}
注意''==在你WeakWrapper未正确执行:它依赖于不同的对象有不同的哈希值,不必是真的。 –
另外(除非我误),不需要'...&Hashable'的需求,因为你无处存取'T'对象的哈希值(只有它的对象标识符) –
@Martin谢谢。我认为ObjectIdentifier总是为任何给定的程序运行返回一个唯一的值?也许是一个新的SO问题的话题。 – MH175