本次我们来聊聊iOS开发中的数据容器,主要从内测管理的角度来分析。从内测管理区别上可以分为两类。
- 强类型
- 弱类型
强类型的容器主要有
NSArray,NSMutableArray,NSSet,NSMutableSet,NSDictionary,NSMutableDictionary。
若类型的容器主要有
NSMapTable,NSHashTable,NSPointerArray。
强类型的容器会对其持有的对象引用计数加1,弱引用的容器不会增加容器里面对象的引用计数。
强引用类型的容器大家应该很熟悉了,本次我们主要来聊聊iOS中弱引用数组。
NSMapTable
NSMapTable 是在 NSDictionary 之后的一个可变集合模型化的类 , 主要特点是在存入数据的时候可以设置对象为weak引用,key 可以不用遵循 NSCopying 协议;key 和 value 的内存管理方式可以分开,如:key 是强引用,value 是弱引用;
它们具有以下区别:
- NSMapTable 会在集合里的对象被回收的时候删除此对象来保持对键 和/或 值保持“弱引用”;
- 当 NSMapTable 添加一个键值对的时候其键或值可以被复制,也可以使用指针标识来进行相等和散列判断;
- 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,特别的是支持弱引用。区别如下:
- NSHashTable可以对其内的成员进行弱引用;
- NSHashTable的成员可以在添加的时候被拷贝一份副本;并且可以控制在将对象添加到NSHashTable中时是否调用对象上的 isEqualTo: 和 hash方法;
- 它可以包含任意指针(其成员不被约束为对象)。
你可以将 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 对象
网友评论