NSSet с NSStrings containsstObject не возвращает YES, когда это должно - PullRequest
13 голосов
/ 12 августа 2011

Я загружаю словарь (список слов, а не класс) в 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 ]

27 голосов
/ 12 августа 2011

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

Мы можем видеть, что две строки имеют разные значения указателя, но набор по-прежнему возвращает YES для вызова containsObject:.

Так что я думаю, выстроки на самом деле не равны.Я бы проверил наличие скрытых пробелов или других подобных проблем.

0 голосов
/ 15 августа 2011

Хорошо, так что я решил проблему, и она не имела ничего общего с методом containsObject.Как я прокомментировал, я использовал Dave DeLongs DDFileReader, найденный здесь: Dave DeLongs DDFileReader

Таким образом, используя CFShow для всего словаря, я заметил, что каждое слово имеет новую строку в конце.Поэтому вместо метода -readLine я использовал -readTrimmedLine (методы бота в вышеупомянутой программе чтения файлов).Это решило проблему для меня.

Для будущих посетителей форума я хотел бы обратить внимание на обсуждение DarkDust и zoul о -containsObject и -member (оба метода NSSet), которые, как оказалось, оба используют-isEqual метод.

0 голосов
/ 12 августа 2011

-[NSSet containsObject:], кажется, проверяет только значение указателя (документации для этого метода очень не хватает), а не равенство объектов. Поэтому вам нужно использовать -[NSSet member:] вместо этого, который использует isEqual:, чтобы проверить, есть ли в вашем наборе объект, который считается равным. if ([dictionary member:test]) NSLog(@"YES!");

Редактировать: На самом деле кажется, что containsObject: также использует isEqual:. Кажется, они только отличаются тем, что возвращают (containsObject: возвращает BOOL, а member: возвращает id). Я оставляю этот ответ для документации.

...