NSSet with NSStrings containsstObject在应该返回YES时不返回YES

时间:2011-08-12 08:29:50

标签: objective-c nsstring nsset

我正在将字典(单词列表,而不是类)加载到NSSet中作为NSStrings。然后我重复发送这个消息-containsObject:someNSString。但它总是返回错误。我写了一些代码来测试它:

NSLog(@"Random from dictionary: %@", [dictionary anyObject]);
NSString *test = [NSString stringWithFormat:@"BEMIRED"];
NSLog(@"To match this word: %@", test);
if ([dictionary containsObject:test])
    NSLog(@"YES!");

在日志中我得到以下内容:

Random from dictionary: BEMIRED
To match this word: BEMIRED

(我错过了“是的!”)

当我尝试使用CFShow(字典)时,我可以看到它实际上包含字符串和所有内容。一个例子:

0 : <CFString 0xc3bd810 [0x1386400]>{contents = "BEMIRED"}
3 : <CFString 0xdf96ef0 [0x1386400]>{contents = "SUBJECTIFIED"}

有人可以帮我吗? 谢谢!

3 个答案:

答案 0 :(得分:27)

NSSet使用isEqual:来测试对象相等性,NSString会覆盖它以执行字符串比较,如您所料。以下单元测试通过:

- (void)testSetStrings
{
    NSSet *set = [NSSet setWithObject:@"String 1"];

    // I've used the UTF8 initializer to avoid any cleverness from reusing objects
    NSString *string1 = [[[NSString alloc] initWithUTF8String:"String 1"] autorelease];

    // Test the references/pointers are not the same
    STAssertTrue([set anyObject] != string1, nil);

    STAssertTrue([set containsObject:string1], nil);
}

我们可以看到两个字符串具有不同的指针值,但该集合仍然为containsObject:调用返回YES。

所以我猜你的琴弦实际上并不相同。我会检查隐藏的空白或其他类似的问题。

答案 1 :(得分:0)

-[NSSet containsObject:]似乎只检查指针值(文档非常缺乏该方法),而不是对象相等。因此,您需要使用-[NSSet member:],而isEqual:使用if ([dictionary member:test]) NSLog(@"YES!"); 来检查被认为是相等的对象是否在您的集合中。

containsObject:

<击>

修改:实际上isEqual:似乎也使用了containsObject:。他们返回的内容似乎不同(BOOL返回member:id返回{{1}})。我让这个答案留下来用于记录目的。

答案 2 :(得分:0)

好的,所以我解决了这个问题,它与containsObject方法无关。正如我评论的那样,我使用了Dave DeLongs DDFileReader:Dave DeLongs DDFileReader

因此,通过在整个字典上使用CFShow,我注意到每个单词的末尾都有一个新行。因此,我使用-readTrimmedLine(上面提到的文件阅读器中的bot方法)而不是-readLine方法。这解决了我的问题。

对于未来的论坛访问者,我想提请注意DarkDust和zoul关于-containsObject和-member(两种NSSet方法)的讨论,结果两者都使用-isEqual方法。