NSDictionary 的内部实现
NSDictionary是IOS中使用的一种key-value容器,参考cocotron的源代码,NSDictionary使用NSMapTable实现。
NSMapTable同样是一个key-value的容器,下面是NSMapTable的部分代码:
typedef struct {
NSMapTable *table;
NSInteger i;
struct _NSMapNode *j;
} NSMapEnumerator;
上述结构体描述了遍历一个NSMapTable时的一个指针对象,其中包含table对象自身的指针,计数值,和节点指针。
typedef struct {
NSUInteger (*hash)(NSMapTable *table,const void *);
BOOL (*isEqual)(NSMapTable *table,const void *,const void *);
void (*retain)(NSMapTable *table,const void *);
void (*release)(NSMapTable *table,void *);
NSString *(*describe)(NSMapTable *table,const void *);
const void *notAKeyMarker;
} NSMapTableKeyCallBacks;
上述结构体中存放的是几个函数指针,用于计算key的hash值,判断key是否相等,retain,release操作。
typedef struct {
void (*retain)(NSMapTable *table,const void *);
void (*release)(NSMapTable *table,void *);
NSString *(*describe)(NSMapTable *table, const void *);
} NSMapTableValueCallBacks;
上述存放的三个函数指针,定义在对nsmaptable插入一对key-value时,对value对象的操作。
@interface NSMapTable : NSObject {
NSMapTableKeyCallBacks *keyCallBacks;
NSMapTableValueCallBacks *valueCallBacks;
NSUInteger count;
NSUInteger nBuckets;
struct _NSMapNode **buckets;
}
上面是NSMtabtable真正的描述,可以看出来NSMapTable是一个哈希+链表的数据结构,因此在NSMapTable中插入或者删除一对对象时
寻找的时间是O(1)+O(m),m最坏时可能为n。
O(1):为对key进行hash得到bucket的位置
O(m):遍历该bucket后面冲突的value,通过链表连接起来。
因此:NSDictionary中的key Value遍历时是无序的,至如按照什么样的顺序,跟hash函数相关。NSMapTable使用NSObject的哈希函数。
-(NSUInteger)hash {
return (NSUInteger)self>>4;
}
上述是NSObject的哈希值的计算方式,简单通过移位实现。右移4位,左边补0.
因为对象大多存于堆中,地址相差4位应该很正常。
@implementation NSDictionary (NSKeyValueCoding)
-(id)valueForKey:(NSString*)key;
{
if([key hasPrefix:@"@"])
return [super valueForKey:[key substringFromIndex:1]];
return [self objectForKey:key];
}
-(void)setValue:(id)value forKey:(NSString*)key
{
[NSException raise:NSInvalidArgumentException format:@"%@ called on immutable dictionary %@", NSStringFromSelector(_cmd), self];
}
@end
@implementation NSMutableDictionary (NSKeyValueCoding)
-(void)setValue:(id)value forKey:(NSString*)key
{
if(value)
[self setObject:value forKey:key];
else
[self removeObjectForKey:key];
}
@end
使用setObject:ForKey时很可能因为value或者key为空导致crash,使用setValue:Forkey就不会。
NSDictionary 的内部实现的更多相关文章
- 非等高cell实战(01)-- 实现微博页面
非等高cell实战(01)-- 实现微博页面 学习过UITableView.AutoLayout以及MVC的相关知识,接下来通过一个微博页面实战来整合一下. 首先看一下效果图: 需求分析 此页面为非等 ...
- (转)ios error:unrecognized selector sent to class
转自:http://blog.itpub.net/12231606/viewspace-1081952/ 今天将app统计的.a静态库包含到一个app应用中,调试时报下面的错误: *** Termin ...
- 非等高cell实战--实现微博页面
代码地址如下:http://www.demodashi.com/demo/11639.html 前言 学习过UITableView.AutoLayout以及MVC的相关知识,接下来通过一个微博页面实战 ...
- iOS - error:unrecognized selector sent to class 导入第三方SDK .a后不识别,运行崩溃
今天将app统计的.a静态库包含到一个app应用中,调试时报下面的错误: *** Terminating app due to uncaught exception 'NSInvalidArgumen ...
- KVO内部实现原理
KVO的原理: 只要给一个对象注册一个监听, 那么在运行时, 系统就会自动给该对象生成一个子类对象, (格式如:NSKVONotifying_className), 并且重写自动生成的子类对象的被监听 ...
- KVO的内部实现原理
kvo概述 kvo,全称Key-Value Observing,它提供了一种方法,当对象某个属性发生改变时,允许监听该属性值变化的对象可以接受到通知,然后通过kvo的方法响应一些操作. kvo实现原理 ...
- OC:属性的内部实现原理、dealloc内释放实例变量、便利构造器方法的实现原理、collection的内存管理
代码: // // main.m #import <Foundation/Foundation.h> #import "Person.h" #import " ...
- NSDictionary所有API的学习。
<欢迎大家增加iOS开发学习交流群:QQ529560119> @property (readonly)NSUInteger count; //1.利用指定的key寻找相应的value - ...
- NSDictionary实现原理-ios哈希hash和isEqual
NSDictionary实现原理-ios哈希hash和isEqual OC中自定义类的NSCopying实现的注意事项(isEqual & hash实现) http://blog.csdn ...
随机推荐
- 关于map()与filter()
def f1(a): if a == 3: pass else: return a*a li = [1,2,3,4] for i in filret(f1,li) print(i) def f1(a) ...
- 使用signalR创建聊天室。
浏览器支持Html5的情况下,SignalR使用WebSockets,当不支持时SignalR将使用其它技术来实现通讯. 界面如下:左侧包含三种聊天对象,不同的聊天对象会创建不同的对话框. 设计思路参 ...
- Ubuntu安装Python机器学习包
1.安装pip $ mkdir ~/.pip $ vi ~/.pip/pip.conf [global] trusted-host=mirrors.aliyun.com index-url=http: ...
- BIEE应用存储过程并从前台传参
1. RPD操作 1.1修改连接池属性 在连接脚本添加SQL,这里选择在查询前执行 新建SQL脚本
- python3 流程控制
表达式if ... else >>> if 3 > 4: ... print('False') ... else: ... print('True') ... True 表达式 ...
- USACO 3.2 Contact
ContactIOI'98 The cows have developed a new interest in scanning the universe outside their farm wit ...
- 使用 JUnit 报错 java.lang.Exception: No runnable methods
错误详情如下: java.lang.Exception: No runnable methods at org.junit.runners.BlockJUnit4ClassRunner.validat ...
- 解决IE兼容总汇【转】
转载声明: 藏羚羊 2014年04月16日 于 前端开拓者 发表 本文固定链接: http://www.frontopen.com/2552.html 1. <meta http-equiv=“ ...
- C# 导出Word
导出word文档(无模版): using Microsoft.Office.Interop.Word; public static string CreateWordFile(CaseVM model ...
- 逆向思维 UVA 11853
题目大意:紫书175 思路:看书...2333 关键点就是利用已知条件来逆向思考是否能走通,而不是傻傻的从某个点开始出发啊啥的.