NSSet с NSStrings containsstObject не возвращает YES, когда он должен
Я загружаю словарь (список слов, а не класс) в NSSet как NSStrings. Затем я повторно отправляю этот набор сообщение -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 (словарь), я вижу, что на самом деле он содержит строки и все. Пример:
0 : <CFString 0xc3bd810 [0x1386400]>{contents = "BEMIRED"}
3 : <CFString 0xdf96ef0 [0x1386400]>{contents = "SUBJECTIFIED"}
Может ли кто-нибудь помочь мне здесь?
Спасибо!
Ответы
Ответ 1
NSSet использует isEqual:
для проверки равенства объектов, которое NSString переопределяет для выполнения сравнения строк, как вы ожидали. Следующее unit test проходит:
- (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);
}
Мы можем видеть, что две строки имеют разные значения указателя, но набор по-прежнему возвращает YES для вызова containsObject:
.
Итак, я бы предположил, что ваши строки на самом деле не равны. Я бы посмотрел на скрытые пробелы или другие подобные проблемы.
Ответ 2
-[NSSet containsObject:]
, похоже, проверяет только значение указателя (для этого метода очень мало документации), а не для равенство объектов. Поэтому вместо этого нужно использовать -[NSSet member:]
, который использует isEqual:
для проверки того, является ли объект, который считается равным, в вашем наборе.
if ([dictionary member:test])
NSLog(@"YES!");
Забастовкa >
Изменить: На самом деле кажется, что containsObject:
также использует isEqual:
. Кажется, что они отличаются только тем, что они возвращают (containsObject:
возвращает a BOOL
, а member:
возвращает id
). Я разрешаю этот ответ оставаться в документации.
Ответ 3
Хорошо, поэтому я решил проблему и не имел никакого отношения к методу containsObject. Как я уже говорил, я использовал Dave DeLongs DDFileReader, найденный здесь: Dave DeLongs DDFileReader
Итак, используя CFShow во всем словаре, я заметил, что каждое слово имеет новую строку в конце. Поэтому вместо метода -readLine я использовал -readTrimmedLine (бот-методы в вышеупомянутом файловом считывателе). Это решило проблему для меня.
Для будущих посетителей форума я хотел бы обратить внимание на обсуждение DarkDust и zoul о -containsObject и -member (оба метода NSSet), который, как оказалось, использует метод -isEqual.