NSDictionary 键是 id 但集合的值只是 id,文档表明它们的值被保留。根据设置集合编程主题的基础知识 docs:
但是,您可以修改单个对象本身(如果它们支持修改)。
如果修改对象,这可能会影响该对象的哈希值,从而影响查找。我认为 NSSet 是快速查找?
下面的示例展示了如果您改变对象,事情会如何崩溃:
NSMutableString *str = [NSMutableString stringWithString: @"AWESOME"];
NSCountedSet *countedSet = [[NSCountedSet alloc] init];
[countedSet addObject: str];
[countedSet addObject: str];
NSLog(@"%@", @([countedSet countForObject: @"AWESOME"]));
[str appendString: @" NOT AWESOME"];
NSLog(@"%@", @([countedSet countForObject: @"AWESOME NOT AWESOME"]));
NSLog(@"%@", @([countedSet countForObject: @"AWESOME"]));
NSLog(@"%@", @([countedSet countForObject: str]));
for(NSString *s in countedSet) {
NSLog(@"%@ - %@", str, @([countedSet countForObject: s]));
}
NSSet *set = [NSSet setWithArray: @[ str ]];
NSLog(@"Set Contains string, %@", @([set containsObject: str]));
[str appendString: @"asdf"];
NSLog(@"Set Contains string, %@", @([set containsObject: str]));
NSLog(@"%@", set);
并用我的解释输出:
[64844:303] 2 // Count is 2
[64844:303] 0 // Count should be 2 - if it looks for the literal string
[64844:303] 0 // Count should be 0, but can't find original object either
[64844:303] 0 // Count should be 2 - asking for actual object that's in there
[64844:303] AWESOME NOT AWESOME - 0 // Should be 2 - asking for actual object that it just retrieved
[64844:303] Set Contains string, 1 // Correct, pre-mutation
[64844:303] Set Contains string, 0 // Should be true, object is in there
[65070:303] {(
"AWESOME NOT AWESOMEasdf" // see? It's in there
)}
My take:
该集合可能基于哈希值的存储桶,当该集合后面的哈希被更改时,它不知道该怎么做并且查找被破坏。该领域缺乏文档。
我的问题重申:
文档说你可以改变对象,这并不直观。
变异对象会破坏集合。
搞什么?