NSHashTable 解决了什么问题
使用 NSMutableSet 时,主要有两个让开发者如鲠在喉的地方:
- 加入NSMutableSet 的只能是对象,还必须得实现NSCopy 协议;
- 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 时,你是如何处理内存问题的?欢迎你的留言,与大家一同讨论最优解。