NSHashTable:NSMutableSet 的替代品?

NSHashTable 解决了什么问题

使用 NSMutableSet 时,主要有两个让开发者如鲠在喉的地方:

  1. 加入NSMutableSet 的只能是对象,还必须得实现NSCopy 协议;
  2. NSMutableSet 强引用对象,这在某些场景下导致内存泄漏。

苹果当然也发现了这些问题,于是iOS 6.0 以后,推出 NSHashTable ,从此我们可以这样:

let hashTable = NSHashTable.init(options: NSHashTableWeakMemory)
hashTable.add(42 as AnyObject) //加入常量也不崩

可以这样:

// 自定义对象,不用实现 NSCopy 协议
class TryObj {
    var name:String
    init(name:String) {
        self.name = name
    }
}
var obj1:TryObj? = TryObj(name:"sameName")
hashTable.add(obj1)

加入空值也不会崩:

hashTable.add(nil)

真是怎么动都不会侧漏崩溃。
NSHashTable 还有一个技能,当保存的对象被释放时,它可以自动处理善后,不用我们操心。

NSHashTable的局限和注意点

这么好用,那么我们是不是应该用 NSHashTable 代替NSMutableSet 就好呢?
当然不是,首先是性能问题,在 add 操作中,NSHashTable所用的时间差不多是NSMutableSet的2倍
其次,NSHashTable的allObjects返回是个数组,依然会有强引用的问题,要注意避免;
另外,NSHashTable并没有完全提供NSMutableSet 的所有方法,比如 filter

开发建议

NSHashTable 提供了 NSMutableSet 的弱引用版本,扩展了 Set 的使用范围,但也带来了低效能和精简的功能,因此开发中首选还是使用NSMutableSet,在确实需要弱引用时,才考虑替换成NSHashTable。

思考题

在你的开发中,发现有哪些场景更适合使用 NSHashTable ?在未使用 NSHashTable 时,你是如何处理内存问题的?欢迎你的留言,与大家一同讨论最优解。

你可能感兴趣的:(NSHashTable:NSMutableSet 的替代品?)