美文网首页
【OC梳理】NSPointerArray、NSMapTable、

【OC梳理】NSPointerArray、NSMapTable、

作者: 忠橙_g | 来源:发表于2018-10-25 16:16 被阅读43次

    NSPointerArray、NSMapTable、NSHashTable是iOS 6.0之后新增的集合类型,对应于原来的NSArray、NSSet、NSDictionary。

    NSPointerArray

    NSPointerArray和NSArray/NSMutableArray一样,用于有序的插入或移除。不同的是:

    • 可以存储 nil,并且 nil 还参与 count 的计算。
    • count 值可以直接设置,如果直接设置count,那么会使用 nil 占位。
    • 可以使用 weak 来修饰元素,可以添加所有的指针类型。
    • 可以通过 for...in 来进行遍历。

    也有一些缺点:

    • 操作均基于 index,无法通过 object 来进行操作;
    • 无法直接插入 array,或用 array 初始化;
    • 查找功能没有 NSArray 强大;
    • 没有逆序、排序等 API 提供

    初始化

    NSPointerArray 有两个初始化方法:

    - (instancetype)initWithOptions:(NSPointerFunctionsOptions)options;
    - (instancetype)initWithPointerFunctions:(NSPointerFunctions *)functions; 
    
    + (NSPointerArray *)pointerArrayWithOptions:(NSPointerFunctionsOptions)options;
    + (NSPointerArray *)pointerArrayWithPointerFunctions:(NSPointerFunctions *)functions;
    

    NSPointerFunctionsOptions主要分为三大类:

    内存管理

    • NSPointerFunctionsStrongMemory:缺省值,在 CG 和 MRC 下强引用成员
    • NSPointerFunctionsZeroingWeakMemory:已废弃,在 GC 下,弱引用指针,防止悬挂指针
    • NSPointerFunctionsMallocMemory 与 NSPointerFunctionsMachVirtualMemory:3 用于 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:根据第二类的选择,来具体处理。

    可以使用多个组合进行初始化:

    NSPointerFunctionsOptions opt = NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality | NSPointerFunctionsCopyIn;
    NSPointerArray *point = [[NSPointerArray alloc]initWithOptions:opt];
    

    NSPointerFunctions
    使用NSPointerFunctions可以自定义NSPointerArray对元素的处理方式:如何内存管理、如何hash、如何判断相等(isEqual)。
    NSPointerFunctions初始化时可设置NSPointerFunctionsOptions

    - (instancetype)initWithOptions:(NSPointerFunctionsOptions)options;
    + (NSPointerFunctions *)pointerFunctionsWithOptions:(NSPointerFunctionsOptions)options;
    

    如果需要自定义实现函数,可以使用下面的对应属性:

    // 自定义指针函数
    // hash函数
    @property (nullable) NSUInteger (*hashFunction)(const void *item, NSUInteger (* _Nullable size)(const void *item));
    // isEqual函数
    @property (nullable) BOOL (*isEqualFunction)(const void *item1, const void*item2, NSUInteger (* _Nullable size)(const void *item));
    // size函数
    @property (nullable) NSUInteger (*sizeFunction)(const void *item);
    // 描述函数
    @property (nullable) NSString * _Nullable (*descriptionFunction)(const void *item);
    
    // 自定义内存配置
    // 移除元素时的处理函数
    @property (nullable) void (*relinquishFunction)(const void *item, NSUInteger (* _Nullable size)(const void *item));
    // 添加元素时的处理函数
    @property (nullable) void * _Nonnull (*acquireFunction)(const void *src, NSUInteger (* _Nullable size)(const void *item), BOOL shouldCopy);
    

    可以自行实现函数,然后将函数指针赋给对应属性即可,比如,isEqual:

    static BOOL IsEqual(const void *item1, const void *item2, NSUInteger (*size)(const void *item)) {
        return *(const int *)item1 == *(const int *)item2;
    }
    
    NSPointerFunctions *functions = [[NSPointerFunctions alloc] init];
    [functions setIsEqualFunction:IsEqual]; 
    

    操作数组

    添加元素:

    - (void)addPointer:(nullable void *)pointer;
    

    移除元素:

    - (void)removePointerAtIndex:(NSUInteger)index; 
    

    插入元素:

    - (void)insertPointer:(nullable void *)item atIndex:(NSUInteger)index;
    

    替换元素:

    - (void)replacePointerAtIndex:(NSUInteger)index withPointer:(nullable void *)item;
    

    如果想实现类似Array的根据下标赋值,可以为它添加一个分类:

    
    @interface NSPointerArray(Set)
    
    /// 设置目标位置的值
    - (void)setObject:(id)anObject
              atIndex:(NSUInteger)idx;
    
    @end
    
    @implementation NSPointerArray(Set)
    
    - (void)setObject:(id)anObject
              atIndex:(NSUInteger)idx{
        if (self.count > idx) {
           self.count = idx + 2;
        }
        [self insertPointer:(__bridge void * _Nullable)(anObject) atIndex:idx];
    }
    
    @end
    

    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 依然会对成员进行强引用。

    相关文章

      网友评论

          本文标题:【OC梳理】NSPointerArray、NSMapTable、

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