美文网首页iOS记录
集合类NSPointerArray,NSMapTable,NSH

集合类NSPointerArray,NSMapTable,NSH

作者: wpf_register | 来源:发表于2021-03-05 15:43 被阅读0次

原文链接

iOS 中有很多种集合类型,最为常见的可能就 NSArray、NSDictionary、NSSet,但其实还有 NSPointerArray、NSMapTable、NSHashTable 等类型,虽然后面三个类型不常见,但确非常重要。

NSPointerArray

对应着 NSArray,先来看看 API 中介绍的特点:

  • 和传统 Array 一样,用于有序的插入或移除;
  • 与传统 Array 不同的是,可以存储 NULL,并且 NULL 还参与 count 的计算;
  • 与传统 Array 不同的是,count 可以 set,如果直接 set count,那么会使用 NULL 占位;
  • 可以使用 weak 来修饰成员;
  • 成员可以是所有指针类型;
  • 遵循 NSFastEnumeration,可以通过 for...in 来进行遍历。
初始化

NSPointerArray 与 NSMutableArray 很像,都是可变有序集合。最大的不同就是它们的初始化方法,NSPointerArray 有两个初始化方法:

- (instancetype)initWithOptions:(NSPointerFunctionsOptions)options;
- (instancetype)initWithPointerFunctions:(NSPointerFunctions *)functions;
NSPointerFunctionsOptions

NSPointerFunctionsOptions,它是个 option,主要分为三大类:

  • 内存管理
    NSPointerFunctionsStrongMemory:缺省值,在 CG 和 MRC 下强引用成员
    NSPointerFunctionsZeroingWeakMemory:已废弃,在 GC 下,弱引用指针,防止悬挂指针
    NSPointerFunctionsMallocMemory 与 NSPointerFunctionsMachVirtualMemory: 用于 Mach 的虚拟内存管理
    NSPointerFunctionsWeakMemory:在 CG 或者 ARC 下,弱引用成员
  • 特性,用于标明对象判等方式
    NSPointerFunctionsObjectPersonality:hash、isEqual、对象描述
    NSPointerFunctionsOpaquePersonality:pointer 的 hash 、直接判等
    NSPointerFunctionsObjectPointerPersonality:pointer 的 hash、直接判等、对象描述
    NSPointerFunctionsCStringPersonality:string 的 hash、strcmp 函数、UTF-8 编码方式的描述
    NSPointerFunctionsStructPersonality:内存 hash、memcmp 函数
    NSPointerFunctionsIntegerPersonality:值的 hash
  • 内存标识
    NSPointerFunctionsCopyIn:根据第二类的选择,来具体处理。如果是 NSPointerFunctionsObjectPersonality,则根据 NSCopying 来拷贝。
NSPointerFunctions

自定义成员的处理方式,如:内存管理、hash、isEqual 等,可以看到 API 中定义了一系列属性,它们都是函数指针,使用注释分段.

NSMapTable

与 NSMapTable 对应的,是 NSMutableDictionary。除了 集合的共有特点以外,比起传统字典,它还有一些优势:

  • key 可以不用遵循 NSCopying 协议;
  • key 和 value 的内存管理方式可以分开,如:key 是强引用,value 是弱引用;
    相比起 NSPointerArray,NSMapTable 的初始化方法要多得多:
#实例方法,虽然有 capacity 参数,但实际没用到
- (instancetype)initWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions capacity:(NSUInteger)initialCapacity;
- (instancetype)initWithKeyPointerFunctions:(NSPointerFunctions *)keyFunctions valuePointerFunctions:(NSPointerFunctions *)valueFunctions capacity:(NSUInteger)initialCapacity;

# 便利构造器
+ (NSMapTable<KeyType, ObjectType> *)mapTableWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions;

#返回指定 key、value 内存管理类型的 map
+ (NSMapTable<KeyType, ObjectType> *)strongToStrongObjectsMapTable NS_AVAILABLE(10_8, 6_0);
+ (NSMapTable<KeyType, ObjectType> *)weakToStrongObjectsMapTable NS_AVAILABLE(10_8, 6_0);
+ (NSMapTable<KeyType, ObjectType> *)strongToWeakObjectsMapTable NS_AVAILABLE(10_8, 6_0);
+ (NSMapTable<KeyType, ObjectType> *)weakToWeakObjectsMapTable NS_AVAILABLE(10_8, 6_0);

其实,这么多的初始化方法就对应着四种搭配:

  • key 为 strong,value 为 strong
  • key 为 strong,value 为 weak
  • key 为 weak,value 为 strong
  • key 为 weak,value 为 weak
    当用 weak 修饰 key 或 value 时,有一方被释放,则该键值对移除。

NSHashTable

NSHashTable 对应 NSMutableSet,它的 API 更为简单,与 NSMapTable 同样,初始化方法的 capacity 并未生效。

- (instancetype)initWithOptions:(NSPointerFunctionsOptions)options capacity:(NSUInteger)initialCapacity;
- (instancetype)initWithPointerFunctions:(NSPointerFunctions *)functions capacity:(NSUInteger)initialCapacity;

值得注意的是,NSHashTable 有一个 allObjectes 的属性,返回 NSArray,即使 NSHashTable 是弱引用成员,allObjects 依然会对成员进行强引用。

应用

例如项目中用到蓝牙,蓝牙的连接、发送、断开等操作,可以封装成了单例,但是很多地方都需要检测蓝牙当前状态,是否连接、是否发送成功等等,所以需要多个回调。
首先考虑传值方式:代理、block、通知。通知一般不太考虑,但是代理和 block 对于单例来说,都只能有一个值,一个对象设置以后,另一个就收不到。对于这种情况,就可以选择使用 NSHashTable。根据 NSHashTable 不持有对象,能添加空对象的特点,几乎完全不会影响成员的生命周期,也不会造成 crash。

所以,还是要先熟悉各种集合的特性,然后去匹配需求,才是最好的。

相关文章

网友评论

    本文标题:集合类NSPointerArray,NSMapTable,NSH

    本文链接:https://www.haomeiwen.com/subject/cuzofltx.html