平时开发中,大部分使用NSDictionaryNSMutableDictionary。下面介绍个特殊的。

NSMapTable

NSMapTable是更广泛意义的NSMutableDictionary,区别于NSMutableDictionaryNSMapTable有如下特性:

使用方法

NSObject *object = [[NSObject alloc] init];
NSMapTable *map = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsWeakMemory valueOptions:NSPointerFunctionsWeakMemory capacity:10];
[map setObject:object forKey:@"key"];
[map removeObjectForKey:@"key"];

NSMapTableOptions介绍(源码中是使用静态常量做关联)

enum {
    // 默认行为,强引用集合中的对象,等同于NSMutableSet
    NSMapTableStrongMemory             = 0,
    // 在将对象添加到集合之前,会拷贝对象
    NSMapTableCopyIn                   = NSPointerFunctionsCopyIn,
    // 使用移位指针(shifted pointer)来做hash检测和确定两个对象是否相等;
    // 同时使用description方法来做描述字符串
    NSMapTableObjectPointerPersonality = NSPointerFunctionsObjectPointerPersonality,
    // 弱引用集合中的对象,且在对象被释放后,会被正确的移除。
    NSMapTableWeakMemory               = NSPointerFunctionsWeakMemory
};
typedef NSUInteger NSMapTableOptions;

NXMapTable

在objc源码中,找到了关于NSMapTable的类似实现。可以参考下

Hash冲突解决方案:开放地址法

NXMapTable存储结构(精简过)

typedef struct _NXMapTable {
    // 附属实体
    const struct _NXMapTablePrototype	* prototype;
    // 真实的长度(存储了多少有效数据)
    unsigned	count;
    // buckets实际所占用的空间大小-1;如果count * 4 > numBuckets * 3 就扩容buckets
    unsigned	nbBucketsMinusOne;
    // 数据[MapPair?]
    void	* buckets;
} NXMapTable;

NXMapTablePrototype存储结构(精简过)

typedef struct _NXMapTablePrototype {
    // hash的函数指针
    unsigned	(* hash)(NXMapTable *,
                                  const void * key);
    // 相等的函数指针
    int		(* isEqual)(NXMapTable *,
                                     const void * key1,
                                     const void * key2);
    // 释放函数指针
    void	(* free)(NXMapTable *,
                                  void * key,
                                  void * value);
    // 预留字段
    int		style;
} NXMapTablePrototype;