对容器中可变类型修改的坑

warning:如果把可变数据存放到容器后尽量不要再次修改!

图文并没有什么关系 这只是个分割线 程序员都是单身狗

No Demo No BB(没Demo说个J8)

用一个NSMutableSet与几个NSMutableArray对象测试

NSMutableSet *set = [NSMutableSet new];
NSMutableArray *array1 = [@[@1, @2] mutableCopy];
[set addObject:array1];
NSLog(@"set = %@", set);

输出结果:set = {((1, 2))}

现在set里含有一个数组对象,数组中包含两个对象。再向set中键入一个数组,与前一个数组所包含的对象相同,顺序也相同,于是,带加入的数组与set中已有的数组是相等的:

NSMutableArray *array2 = [@[@1, @2] mutableCopy];
[set addObject:array2];
NSLog(@"set = %@", set);

输出结果:set = {((1, 2))}
     set = {((1, 2))}

此时set中仍然只有一个对象:* 因为刚才要加入的那个数组对象和set中已有的数组对象相等,所以set并不会改变 *。
这次来添加一个和set中已有的对象不同的数组:

NSMutableArray *array3 = [@[@1] mutableCopy];
[set addObject:array3];
NSLog(@"set = %@", set);

输出结果:set = {((1), (1, 2))}

由于array3set里已有的对象不相等,所以现在set里有两个数组了,一个是最开始加入的,一个是刚才新添加的。
现在改变下array3的内容,令其和最开始的那个数组相等:

[array3 addObject:@2];
NSLog(@"set = %@", set);

输出结果:set = {((1, 2), (1, 2))}

现在你会发现set中竟然有两个彼此相同的数组!

根据set的语义是不允许出现这种情况的,然而结果却无法保证这一点了,因为我们修改了set中已有的对象。
若此时拷贝此set,结果更坑爹:

NSSet *setB = [set copy];
NSLog(@"setB = %@", setB);

输出结果:set = {((1, 2), (1, 2))}
     setB = {((1, 2))}

复制过的set中又只剩一个对象了!

这个set看上去好像是由一个空set开始,通过逐个向其中添加新对象创建出来的。
也许你会觉得这样做没什么问题,也许你会想要一个”照原样“复制出来的那个“问题”set。

总之:如果把某个对象放在set后又修改其内容,那么结果真的很难预料。

PS:图片在网上找的,侵删。

推荐阅读更多精彩内容