NSObject的hash方法,NSObjecthash方法
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 值來確保過濾掉重複的對象。