如何调整NSMutableDictionary的内存布局以适应存储?

摘要:有关NSDictionary的内存布局,可以参看《NSDictionary 的内存布局》。 1 类图 和《NSDictionary 的内存布局》中的类图相比较,本章类图多了2个新成员: __NSDictionaryM __NSCFDicti
有关NSDictionary的内存布局,可以参看《NSDictionary 的内存布局》。 1 类图 和《NSDictionary 的内存布局》中的类图相比较,本章类图多了2个新成员: __NSDictionaryM __NSCFDictionary 2 __NSDictionaryM 通过下面的方式,可以创建__NSDictionaryM: NSMutableDictionary *dictM = [NSMutableDictionary dictionary]; NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:@{"kaaa": @"aaa"}]; 从Xcode的控制台输出可以看到: (lldb) po [dictM class] __NSDictionaryM 2.1 初始化 __NSDictionaryM的初始化流程和__NSDictionaryI类似。 当调用+[NSMutableDictionary dictionaryWithDictionary:]方法时,最终会调用到-[__NSPlaceholderDictionary initWithObjects:forKeys:count]方法。 -[__NSPlaceholderDictionary initWithObjects:forKeys:count]方法在NSDictionary部分已经介绍过。 这里重新贴出与__NSDictionaryM相关的伪代码: // -[__NSPlaceholderDictionary initWithObjects:forKeys:count] @interface __NSPlaceholderDictionary ... @end @implementation __NSPlaceholderDictionary - (instancetype)initWithObjects:(ObjectType const[])objects forKeys:(ObjectTpye const[])keys count:(NSUInteger)count { ... label: if (self == ___immutablePlaceholderDictionary) { ... } else if (self == ___mutablePlaceholderDictionary) { // 创建 __NSDictionaryM return __NSDictionaryM_new(keys, objecs, count, 3); } error "创建出错" } 从伪代码可以看到,最终会调用到__NSDictionaryM_new方法。 下面就来看看__NSDictionaryM_new的内部实现。 和创建__NSDictionaryI对象一样,__NSDictionaryM_new一开始也需要遍历__NSDictionaryCapacities数组。 遍历的目的,同样是为了找到一个index,这个index对应的capacity大于或者等于count。 BOOL found = NO; NSInteger index = 0; for (; index < 40; index++) { if (__NSDictionaryCapacity[i] >= count) { found = YES; break; } } if (!found) { error "不能创建 NSDictionary"; } 从上面伪代码可以看到,创建__NSDictionaryI最多遍历64项,而这里只遍历40项。 有了index,就可以从__NSDictionarySizes数组中,得到要创建的字典的size。
阅读全文