OC,任何实例对象的哈希值都会在初始化后发生变化?
OC ,any Instance objects's hash will change after init?
1.every对象只有hash,不等于其他对象?
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
obj1.hash != obj2.hash
object'hash 基于什么?
当我更改对象的属性时,2.object 的哈希值永远不会改变???
或
(对象哈希后的对象初始化不能改变???)
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
NSObject *obj3 = [[NSObject alloc] init];
NSDictionary *dic = @{@(obj1.hash):obj1,@(obj2.hash):obj2,@(obj3.hash):obj3,...};
以上两个问题我都不知道,所以我不确定我写的是否正确。
其他(英语不是我的母语,语法错误见谅)
正如@Sulthan所说,hash的默认实现是object
的地址。
在你的子class中,你可以覆盖-hash
方法,你可以根据你的属性计算散列,如果是这样,当你改变属性时,hash
会改变。
例如:NSMutableString
,你可以查看日志看结果,当你改变NSMutableString
的内容时,它的hash改变了。
NSMutableString *s = [[NSMutableString alloc] initWithString:@"124"];
NSLog(@"%@", @([s hash]));
[s appendString:@"123"];
NSLog(@"%@", @([s hash]));
当您覆盖 hash
方法并将该 class 的实例添加到使用对象的散列来定位对象的集合中时,您必须确保散列函数永远不会改变。
在苹果的文档中,谈到了NSObject协议中的hash
方法:
If two objects are equal (as determined by the isEqual: method), they must have the same hash value. This last point is particularly important if you define hash in a subclass and intend to put instances of that subclass into a collection.
If a mutable object is added to a collection that uses hash values to determine the object’s position in the collection, the value returned by the hash method of the object must not change while the object is in the collection. Therefore, either the hash method must not rely on any of the object’s internal state information or you must make sure the object’s internal state information does not change while the object is in the collection. Thus, for example, a mutable dictionary can be put in a hash table but you must not change it while it is in there. (Note that it can be difficult to know whether or not a given object is in a collection.)
这是一个例子:
@interface Object : NSObject
@property (nonatomic) NSInteger ttt;
@end
@implementation Object
- (NSUInteger)hash {
return _ttt;
}
@end
NSMutableSet *set = [NSMutableSet set];
Object *obj = [[Object alloc] init];
obj.ttt = 10;
[set addObject:obj];
obj.ttt = 9;
[set addObject:obj];
NSLog(@"%@", @(set.count));
即使 obj
是同一个对象,结果也是 2。原因是 NSMutableSet 使用 hash
来确定集合中是否已经存在一个对象。您可以想象有一个简单的散列 table,obj
首次插入集合时位于 10。然后你把ttt
属性改成9,它的hash变了,NSMutableSet
发现9的位置是空的,所以又在9的位置插入对象。
1.every对象只有hash,不等于其他对象?
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
obj1.hash != obj2.hash
object'hash 基于什么?
当我更改对象的属性时,2.object 的哈希值永远不会改变???
或
(对象哈希后的对象初始化不能改变???)
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
NSObject *obj3 = [[NSObject alloc] init];
NSDictionary *dic = @{@(obj1.hash):obj1,@(obj2.hash):obj2,@(obj3.hash):obj3,...};
以上两个问题我都不知道,所以我不确定我写的是否正确。
其他(英语不是我的母语,语法错误见谅)
正如@Sulthan所说,hash的默认实现是object
的地址。
在你的子class中,你可以覆盖-hash
方法,你可以根据你的属性计算散列,如果是这样,当你改变属性时,hash
会改变。
例如:NSMutableString
,你可以查看日志看结果,当你改变NSMutableString
的内容时,它的hash改变了。
NSMutableString *s = [[NSMutableString alloc] initWithString:@"124"];
NSLog(@"%@", @([s hash]));
[s appendString:@"123"];
NSLog(@"%@", @([s hash]));
当您覆盖 hash
方法并将该 class 的实例添加到使用对象的散列来定位对象的集合中时,您必须确保散列函数永远不会改变。
在苹果的文档中,谈到了NSObject协议中的hash
方法:
If two objects are equal (as determined by the isEqual: method), they must have the same hash value. This last point is particularly important if you define hash in a subclass and intend to put instances of that subclass into a collection. If a mutable object is added to a collection that uses hash values to determine the object’s position in the collection, the value returned by the hash method of the object must not change while the object is in the collection. Therefore, either the hash method must not rely on any of the object’s internal state information or you must make sure the object’s internal state information does not change while the object is in the collection. Thus, for example, a mutable dictionary can be put in a hash table but you must not change it while it is in there. (Note that it can be difficult to know whether or not a given object is in a collection.)
这是一个例子:
@interface Object : NSObject
@property (nonatomic) NSInteger ttt;
@end
@implementation Object
- (NSUInteger)hash {
return _ttt;
}
@end
NSMutableSet *set = [NSMutableSet set];
Object *obj = [[Object alloc] init];
obj.ttt = 10;
[set addObject:obj];
obj.ttt = 9;
[set addObject:obj];
NSLog(@"%@", @(set.count));
即使 obj
是同一个对象,结果也是 2。原因是 NSMutableSet 使用 hash
来确定集合中是否已经存在一个对象。您可以想象有一个简单的散列 table,obj
首次插入集合时位于 10。然后你把ttt
属性改成9,它的hash变了,NSMutableSet
发现9的位置是空的,所以又在9的位置插入对象。