iOS 容器

作者: saber_zz | 来源:发表于2021-04-09 15:13 被阅读0次

    本次我们来聊聊iOS开发中的数据容器,主要从内测管理的角度来分析。从内测管理区别上可以分为两类。

    • 强类型
    • 弱类型

    强类型的容器主要有
    NSArray,NSMutableArray,NSSet,NSMutableSet,NSDictionary,NSMutableDictionary

    若类型的容器主要有
    NSMapTable,NSHashTable,NSPointerArray

    强类型的容器会对其持有的对象引用计数加1,弱引用的容器不会增加容器里面对象的引用计数。
    强引用类型的容器大家应该很熟悉了,本次我们主要来聊聊iOS中弱引用数组。

    NSMapTable

    NSMapTable 是在 NSDictionary 之后的一个可变集合模型化的类 , 主要特点是在存入数据的时候可以设置对象为weak引用,key 可以不用遵循 NSCopying 协议;key 和 value 的内存管理方式可以分开,如:key 是强引用,value 是弱引用;

    它们具有以下区别:

    1. NSMapTable 会在集合里的对象被回收的时候删除此对象来保持对键 和/或 值保持“弱引用”;
    2. 当 NSMapTable 添加一个键值对的时候其键或值可以被复制,也可以使用指针标识来进行相等和散列判断;
    3. NSMapTable 可以包含任意指针(其内容不被约束为对象)。

    你可以将 NSMapTable 实例配置为对任意指针进行操作,而不仅仅是对象,鼓励使用 C 的 API: void * 指针来操作。 基于对象的 API(例如 setObject:forKey :)将无法在不进行类型转换的情况下对无对象指针操作。

    配置映射表时,请注意,只有NSMapTableOptions中列出的选项才能保证其余的API能够正常工作,包括复制,归档和快速枚举。虽然其他NSPointerFunctions选项用于某些配置,例如保留任意指针,但并不是所有选项的组合都有效。使用某些组合时映射表可能无法正常工作,甚至可能无法正确初始化。

    创建方法

    • (instancetype)initWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions capacity:(NSUInteger)initialCapacity

    通过指定的选项来初始化NSMapTable对象;

    keyOptions:一个位域,用于指定地NSMapTable中的键的选项。
    valueOptions:一个位域,用于指定地NSMapTable中的值的选项
    initialCapacity:NSMapTable的初始容量。 这只是一个提示; 随后可以根据需要增加和缩小NSMapTable。

    用来指定NSMapTable对象中元素(键和值)的行为的常量。

    NSHashTable

    NSHashTable类似于NSSet,特别的是支持弱引用。区别如下:

    1. NSHashTable可以对其内的成员进行弱引用;
    2. NSHashTable的成员可以在添加的时候被拷贝一份副本;并且可以控制在将对象添加到NSHashTable中时是否调用对象上的 isEqualTo: 和 hash方法;
    3. 它可以包含任意指针(其成员不被约束为对象)。

    你可以将 NSHashTable 实例配置为对任意指针进行操作,而不仅仅是对象,鼓励使用 C 的 API: void * 指针来操作。基于对象的 API(例如 addObject:)将无法在不进行类型转换的情况下对无对象指针操作。

    由于它的一些选项,NSHashTable不是一个集合,因为它可以有不同的行为(例如,如果指定了两个isEqual:相等的字符串可能都被添加)。

    配置NSHashTable时,请注意,只有NSHashTableOptions中列出的选项才能保证其余的API能正常工作,包括复制,归档和快速枚举。 虽然其他NSPointerFunctions选项用于某些配置,例如保留任意指针,但并不是所有选项的组合都有效。 使用某些组合,NSHashTable可能无法正常工作,甚至可能无法正确初始化。

    • (instancetype)initWithOptions:(NSPointerFunctionsOptions)options capacity:(NSUInteger)initialCapacity

    根据使用的属性来初始化NSHashTable;

    options:NSHashTable里面元素的支持的选项;
    initialCapacity:NSHashTable可以容纳的元素的初始数量。

    NSPointerArray

    NSPointerArray是以NSArray为模型的,增加了内存管理策略。可以存放nil。
    我们先来了解下NSPointerFunctionsOptions & NSPointerFunctions
    NSPointerFunctions是用来自定义容器对象一些action,入判等,大小等
    NSPointerFunctionsOptions

    typedef NS_OPTIONS(NSUInteger, NSPointerFunctionsOptions) {
        // Memory options are mutually exclusive
        
        // default is strong
        NSPointerFunctionsStrongMemory API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (0UL << 0),       // use strong write-barrier to backing store; use GC memory on copyIn
        NSPointerFunctionsZeroingWeakMemory API_DEPRECATED("GC no longer supported", macos(10.5, 10.8)) API_UNAVAILABLE(ios, watchos, tvos) = (1UL << 0),  // deprecated; uses GC weak read and write barriers, and dangling pointer behavior otherwise
        NSPointerFunctionsOpaqueMemory API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (2UL << 0),
        NSPointerFunctionsMallocMemory API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (3UL << 0),       // free() will be called on removal, calloc on copyIn
        NSPointerFunctionsMachVirtualMemory API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (4UL << 0),
        NSPointerFunctionsWeakMemory API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)) = (5UL << 0),         // uses weak read and write barriers appropriate for ARC
        
        // Personalities are mutually exclusive
        // default is object.  As a special case, 'strong' memory used for Objects will do retain/release under non-GC
        NSPointerFunctionsObjectPersonality API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (0UL << 8),         // use -hash and -isEqual, object description
        NSPointerFunctionsOpaquePersonality API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (1UL << 8),         // use shifted pointer hash and direct equality
        NSPointerFunctionsObjectPointerPersonality API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (2UL << 8),  // use shifted pointer hash and direct equality, object description
        NSPointerFunctionsCStringPersonality API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (3UL << 8),        // use a string hash and strcmp, description assumes UTF-8 contents; recommended for UTF-8 (or ASCII, which is a subset) only cstrings
        NSPointerFunctionsStructPersonality API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (4UL << 8),         // use a memory hash and memcmp (using size function you must set)
        NSPointerFunctionsIntegerPersonality API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (5UL << 8),        // use unshifted value as hash & equality
    
        NSPointerFunctionsCopyIn API_AVAILABLE(macos(10.5), ios(6.0), watchos(2.0), tvos(9.0)) = (1UL << 16),      // the memory acquire function will be asked to allocate and copy items on input
    };
    

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

    内存管理

    NSPointerFunctionsStrongMemory:默认值,强引用成员

    NSPointerFunctionsZeroingWeakMemory:已废弃,在 GC 下,弱引用指针,防止悬挂指针

    NSPointerFunctionsMallocMemory 与 NSPointerFunctionsMachVirtualMemory: 用于 Mach 的虚拟内存管理

    NSPointerFunctionsWeakMemory:弱引用成员

    特性,用于标明对象判等方式

    NSPointerFunctionsObjectPersonality:hash、isEqual、对象描述

    NSPointerFunctionsOpaquePersonality:pointer 的 hash 、直接判等

    NSPointerFunctionsObjectPointerPersonality:pointer 的 hash、直接判等、对象描述

    NSPointerFunctionsCStringPersonality:string 的 hash、strcmp 函数、UTF-8 编码方式的描述

    NSPointerFunctionsStructPersonality:内存 hash、memcmp 函数

    NSPointerFunctionsIntegerPersonality:值的 hash

    内存标识

    NSPointerFunctionsCopyIn:根据第二类的选择,来具体处理。如果是 NSPointerFunctionsObjectPersonality,则根据 NSCopying 来拷贝。

    所以在使用时,可以多个组合,比如:需要强引用成员、使用对象方式对比、并且 add 时 copy 对象

    相关文章

      网友评论

        本文标题:iOS 容器

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