13

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

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(dictionary) 时,我可以看到它实际上包含字符串和所有内容。一个例子:

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

任何人都可以在这里帮助我吗?谢谢!

4

3 回答 3

28

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);
}

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

所以我猜你的字符串实际上并不相等。我会检查隐藏的空格或其他类似问题。

于 2011-08-12T10:17:24.417 回答
0

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

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

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

于 2011-08-15T18:00:25.750 回答
0

似乎只检查指针值(该-[NSSet containsObject:]方法的文档非常缺乏),而不是对象相等性。所以你需要使用-[NSSet member:]isEqual:来检查一个被认为相等的对象是否在你的集合中。

if ([dictionary member:test])
    NSLog(@"YES!");

编辑:实际上它似乎containsObject:也有用isEqual:。它们似乎只在返回的内容上有所不同(containsObject:返回一段BOOL时间member:返回id)。我让这个答案保留用于文档目的。

于 2011-08-12T08:36:25.723 回答