我在NSTextView中有以下字符串:


  荷鲁斯为父亲奥西里斯(Osiris)报仇


为其分配了两个标签,分别为HorusOsiris。我使用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];
    }
}


当frist标签(在上面的示例中为Horus)位于扫描字符串的开头(位置= 0)时,此操作将失败。找不到该标记,并且代码不断循环。

但是,当我将字符串替换为:


  十年后,荷鲁斯为父亲奥西里斯(Osiris)报仇


...一切正常,并且找到了我的两个标签(如预期)并突出显示了。

我是否缺少某些东西,或者这是NSScanner中的错误?

最佳答案

请参阅有关的文档


  - (BOOL)scanUpToString:(NSString *)stopString intoString:(NSString **)stringValue
  
  如果stopString是接收方中的第一个字符串,则该方法返回NO,并且stringValue不变。


扫描程序已找到该字符串,但返回NO,因为它没有通过任何字符进行扫描。这样,您的代码就不会增加position变量,因为该部分在if (result)块内。

我认为删除if语句应该可以解决问题。如果扫描程序找不到stopString,则while条件将失败,并且代码根本不会进入循环。

关于cocoa - NSScanner的出色行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8717028/

10-16 10:29