Замечательное поведение от NSScanner - PullRequest
0 голосов
/ 03 января 2012

У меня есть следующая строка в NSTextView:

Хорус отомстил за своего отца Осириса

Для этого есть два тега, Horus и Osiris,Я использую NSScanner, чтобы отсканировать строку для обоих тегов и выделить их желтым фоном, когда он найден.

Код:

for (Tag *aTag in tags) {
    NSString *aTagName = [aTag name];
    NSUInteger strLength = [aTagName length];
    NSScanner *aScanner = [[NSScanner alloc] initWithString: aString];
    [aScanner setCaseSensitive: YES];
    [aScanner setScanLocation: 0];
    BOOL result = [aScanner scanUpToString: aTagName intoString: nil];
    while (![aScanner isAtEnd]) {
        NSUInteger position = [aScanner scanLocation];
        if (result) {
            NSRange aRange = NSMakeRange(position, strLength);
            [storage removeAttribute: NSBackgroundColorAttributeName range: aRange];
            if (onOrOff) {
                [storage addAttribute: NSBackgroundColorAttributeName value: aColor range: aRange];
            }
            position = position + [aTagName length];
            [aScanner setScanLocation: position];
        }
        [aScanner scanUpToString: aTagName intoString: nil];
    }
}

Это не удается, когда первый тег (в приведенном выше примереHorus) находится в самом начале (местоположение = 0) отсканированной строки.Тег не найден, и код продолжает циклически повторяться.

Однако, когда я заменяю строку на:

Через 10 лет Гор отомстил за своего отца Осириса

... все это работает, и оба моих тега найдены (как и ожидалось) и приятно выделены.

Я что-то упустил или это ошибка в NSScanner?

1 Ответ

2 голосов
/ 04 января 2012

См. Документы для

- (BOOL)scanUpToString:(NSString *)stopString intoString:(NSString **)stringValue

Если stopString является первой строкой в ​​получателе, то метод возвращает NO, а stringValue не изменяется.

Сканер обнаружил строку, но вернул НЕТ, потому что он не сканировал никакие символы для этого.Ваш код не увеличивает переменную position, потому что эта часть находится внутри блока if (result).

Я думаю, что удаление оператора if должно решить проблему.Если сканер не найдет stopString, условие while не будет выполнено, и код вообще не попадет в цикл.

...