https://github.com/YouXianMing

NSObject的hash方法

NSObject的hash方法

 

说明

本示例仅仅演示一个对象什么时候执行hash方法。

 

细节

1. 必要的Model类,重载了hash方法用以反映Hash方法是否被调用了

2. 测试

//
//  ViewController.m
//  Hash
//
//  Created by YouXianMing on 16/4/15.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "Model.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Model *model = [Model new];
    
    [model hash];
    model = nil;
}

@end

3. 测试 isEqual: 方法执行的时候是否会执行 hash 方法,打印情况里面是没有的

//
//  ViewController.m
//  Hash
//
//  Created by YouXianMing on 16/4/15.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "Model.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Model *modelA = [Model new];
    Model *modelB = [Model new];
    
    if ([modelA isEqual:modelB]) {
        
        NSLog(@"YES");
        
    } else {
    
        NSLog(@"NO");
    }
}

@end

4. 用 NSMutableSet 添加对象,这时候会执行hash方法,至于为何会执行2回 _(:з」∠)_ ?

//
//  ViewController.m
//  Hash
//
//  Created by YouXianMing on 16/4/15.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "Model.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Model        *model = [Model new];
    NSMutableSet *set   = [NSMutableSet set];
    
    [set addObject:model];
}

@end

5. 用 NSMutableArray 添加对象测试一下,发现不会执行 hash 方法

//
//  ViewController.m
//  Hash
//
//  Created by YouXianMing on 16/4/15.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "Model.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Model          *model = [Model new];
    NSMutableArray *array = [NSMutableArray array];
    
    [array addObject:model];
}

@end

6. 用作 NSMutableDictionary 中的 object 时,hash 方法不会执行

//
//  ViewController.m
//  Hash
//
//  Created by YouXianMing on 16/4/15.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "Model.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Model               *model      = [Model new];
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    
    [dictionary setObject:model forKey:@"A"];
    [dictionary objectForKey:@"A"];
}

@end

7. 用作 NSMutableDictionary 中的 key 时,hash 方法执行了,不过崩溃了,因为 Model 类没有实现 NSCopying 协议

//
//  ViewController.m
//  Hash
//
//  Created by YouXianMing on 16/4/15.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "Model.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Model               *model      = [Model new];
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    
    [dictionary setObject:@"A" forKey:model];
}

@end

8. NSSet 在初始化的时候添加了 model 并不会让 model 执行 hash 方法

//
//  ViewController.m
//  Hash
//
//  Created by YouXianMing on 16/4/15.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "Model.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Model *model = [Model new];
    
    NSSet *set = [NSSet setWithObjects:model, nil];
    
    if ([[set anyObject] isEqual:model]) {
        
        NSLog(@"A");
    }
    
    set = nil;
}

@end

9. 在创建不可变数组时,model 作为 key 会执行 hash 方法,但同样会崩溃,因为 Model 类没有实现 NSCopying 协议

//
//  ViewController.m
//  Hash
//
//  Created by YouXianMing on 16/4/15.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "Model.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Model        *model      = [Model new];
    NSDictionary *dictionary = @{model : @"A"};
    dictionary = nil;
}

@end

 

总结

一个对象在用作key值时,其 hash 方法会被调用,用以生成一个唯一标识符,NSDictionary 需要根据唯一 key 值(根据 hash 算法生成的值)查找对象, NSSet 需要根据 hash 值来确保过滤掉重复的对象。

posted @ 2016-04-15 22:52  YouXianMing  阅读(3864)  评论(0编辑  收藏  举报