NSMutableSet removeObject未按预期工作

时间:2014-06-30 19:53:11

标签: ios objective-c nsmutableset

我正在使用包含可变对象的对象的NSMutableSet。我在尝试删除已经变异的对象时发现NSMutableSet不一致。

为了隔离问题,我编写了一个快速测试来说明问题(如果有的话):

示例1:按预期工作

NSMutableSet *colors = [[NSMutableSet alloc] init];
NSMutableString *color1 = [[NSMutableString alloc] initWithString:@"Blue"];
NSMutableString *color2 = [[NSMutableString alloc] initWithString:@"Green"];
[colors addObject:color1];
[colors addObject:color2];
NSLog(@"%@",[colors description]); // {( Green, Blue )}
[color1 insertString:@"Cobalt " atIndex:0]; 
NSLog(@"%@",[colors description]); // {( Green, "Cobalt Blue" )}
[colors removeObject:color1];
NSLog(@"%@",[colors description]); {( Green )}

示例2:不按预期工作

NSMutableSet *surnames = [[NSMutableSet alloc] init];
NSMutableString *surname1 = [[NSMutableString alloc] initWithString:@"Brown"];
NSMutableString *surname2 = [[NSMutableString alloc] initWithString:@"Homes"];
[surnames addObject:surname1];
[surnames addObject:surname2];
NSLog(@"%@",[surnames description]); // {( Homes, Brown )}

[surname1 appendString:@"ie"];
NSLog(@"%@",[surnames description]); // {( Homes, Brownie )}
[surnames removeObject:surname1];
NSLog(@"%@",[surnames description]); // {( Homes, Brownie )}

NSString *surnameToRemove = nil;
for (NSString *surname in surnames) {
    if ([surname isEqualToString:@"Brownie"]) {
        surnameToRemove = surname;
        break;
    }
}
[surnames removeObject:surnameToRemove];
NSLog(@"%@",[surnames description]); // {( Homes, Brownie )}

示例2 所示,在变异surname1之后,removeObject即使在通过搜索引用它之后也没有删除它。为什么会这样?可变容器不能包含可变对象吗?

我在this post中读到NSSet缓存所包含对象的哈希值,这可能是问题所在。如果是这样,有没有办法清理它?任何替代解决方案?

为了好奇,为什么示例1 正在运作?

更新

来自Apple's Collection Programming Topics

  

如果可变对象存储在一个集合中,那么就是哈希方法   对象不应该依赖于可变对象的内部状态   或者可变对象在它们处于集合中时不应被修改。   例如,可变字典可以放在一个集合中,但您必须   当它在那里时不要改变它。 (注意,它可能很难   知道给定对象是否在集合中。)

更新2:

重要的是,如果您在Mac或iOS应用上运行,示例2 将返回不同的日志输出:

登录Mac应用程序(按预期工作):

{( Green, Blue )}
{( Green, "Cobalt Blue" )}
{( Green )}
{( Brown, Homes )}
{( Brownie, Homes )}
{( Homes )}
-[__NSSetM removeObject:]: object cannot be nil

登录iOS应用程序(无法正常工作):

{( Green, Blue )}
{( Green, "Cobalt Blue" )}
{( Green )}
{( Homes, Brown )}
{( Homes, Brownie )}
{( Homes, Brownie )}
{( Homes, Brownie )}

更新3:

示例2 相同的代码,但NSMutableArray似乎有效......所以猜测NSMutableSet如何使用哈希。我相信在the linked thread above中对其进行了评论:

NSMutableArray *surnames = [[NSMutableArray alloc] init];
NSMutableString *surname1 = [[NSMutableString alloc] initWithString:@"Brown"];
NSMutableString *surname2 = [[NSMutableString alloc] initWithString:@"Homes"];
[surnames addObject:surname1];
[surnames addObject:surname2];
NSLog(@"%@",[surnames description]);  // {( Homes, Brown )}
[surname1 appendString:@"ie"];
NSLog(@"%@",[surnames description]);  // {( Homes, Brownie )}
[surnames removeObject:surname1];
NSLog(@"%@",[surnames description]);  // {( Homes )}

0 个答案:

没有答案