NSDictionary实现原理
来源:互联网 发布:mac照片导出 编辑:程序博客网 时间:2024/06/07 01:55
NSDictionary(字典)是使用 hash表来实现key和value之间的映射和存储的, hash函数设计的好坏影响着数据的查找访问效率。数据在hash表中分布的越均匀,其访问效率越高。而在Objective-C中,通常都是利用NSString 来作为键值,其内部使用的hash函数也是通过使用 NSString对象作为键值来保证数据的各个节点在hash表中均匀分布。
见NSDictionary中最常用的一个方法原型:
- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
从这个方法中可以知道, 要作为 Key 值,必须遵循 NSCopying 协议。也就是说在NSDictionary内部,会对 aKey 对象 copy 一份新的。而 anObject 对象在其内部是作为强引用(retain或strong)。所以在MRC下,向该方法发送消息之后,我们会向anObject发送 release 消息进行释放。
既然知道了作为 key 值,必须遵循 NSCopying 协议,说明除了 NSString 对象之外,我们还可以使用其他类型对象来作为 NSDictionary 的 key值。不过这还不够,作为 key 值,该类型还必须继承于 NSObject 并且要重载一下两个方法:
- (NSUInteger)hash;
- (BOOL)isEqual:(id)object;
其中,hash 方法是用来计算该对象的 hash 值,最终的 hash 值决定了该对象在 hash 表中存储的位置。所以同样,如果想重写该方法,我们尽量设计一个能让数据分布均匀的 hash 函数。
isEqual 方法是为了通过 hash 值来找到 对象 在hash 表中的位置。
下面,我根据一个小Demo来自定义一个作为 NSDictionary 的 key 值的类。见代码:
KeyObject.h文件:
//// KeyObject.h// KeyDemo//// Created by linshaolie on 14-11-26.// Copyright (c) 2014年 lin. All rights reserved.//#import <Foundation/Foundation.h>@interface KeyObject : NSObject<NSCopying> //实现Copying协议//作为hash值@property(nonatomic, readonly) NSUInteger hashValue;- (instancetype)initWithHashI:(NSUInteger)i;@endKeyObject.m文件:
//// KeyObject.m// KeyDemo//// Created by linshaolie on 14-11-26.// Copyright (c) 2014年 lin. All rights reserved.//#import "KeyObject.h"@interface KeyObject ()//作为hash值@property(nonatomic) NSUInteger hashValue;@end@implementation KeyObject- (instancetype)initWithHashValue:(NSUInteger)hashValue{ self = [super init]; if ( self ) { _hashValue = hashValue; } return self;}#pragma mark -overload methor- (BOOL)isEqual:(id)object{ //根据hash值判断是否是同一个键值 return ([self hashKeyValue] == [(typeof(self))object hashKeyValue]);}- (NSUInteger)hash{ return [self hashKeyValue]; //返回哈希值}#pragma mark -NSCopying- (id)copyWithZone:(NSZone *)zone{ KeyObject *obj = [KeyObject allocWithZone:zone]; obj.hashValue = self.hashValue; return obj;}#pragma mark -private methor//哈希函数- (NSUInteger)hashKeyValue{ return _hashValue % 7; //这里哈希函数用了简单的对7取余}@end
ViewController.m文件:(测试)
//// ViewController.m// KeyDemo//// Created by lin on 14-11-26.// Copyright (c) 2014年 linshaolie. All rights reserved.//#import "ViewController.h"#import "KeyObject.h"@interface ViewController (){ CGPoint _oldPoint; CGMutablePathRef _pathRef; UIImageView *_imageView;}@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; //Test... KeyObject *key1 = [[KeyObject alloc] initWithHashValue:1]; NSMutableDictionary *dic = [[NSMutableDictionary alloc] init]; [dic setObject:@"AAA" forKey:key1]; KeyObject *key2 = [[KeyObject alloc] initWithHashValue:8]; [dic setObject:@"BBB" forKey:key2]; KeyObject *key3 = [[KeyObject alloc] initWithHashValue:3]; [dic setObject:@"CCC" forKey:key3]; NSLog(@"%@", [dic objectForKey:key2]); NSLog(@"%@", [dic allKeys]); NSLog(@"%@", [dic allValues]);}@end
输出结果:
在调用 setObject: forKey: 后,内部会去调用 key 对象的 hash 方法确定 object 在hash表内的入口位置,然后会调用 isEqual 来确定该值是否已经存在于 NSDictionary中。
- NSDictionary实现原理
- NSDictionary实现原理
- NSDictionary实现原理
- iOS NSDictionary(字典)~实现原理
- 实现NSDictionary的深层拷贝
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- NSDictionary
- GitHub上搭建个人网站
- 缓冲流-BufferedXXXXStream
- cglib动态代理介绍(二)
- github优秀开源项目大全-iOS
- 递归练习之求 x 的 N 次方
- NSDictionary实现原理
- 抓取网页时需要主页的一些问题
- Unity界面的操作
- 中文 iOS/Mac 开发博客列表
- java堆栈(转)
- Jlink RTT弱爆了,Jlink Scope来啦
- WebService详解以及C#如何创建WebService和WebService的引用
- 15款Cocos2d-x游戏源码汇总
- 读写配置文件