0

NSTextView に次の文字列があります。

ホルスは父オシリスの仇を討った

Horusこれにはとの 2 つのタグが割り当てられています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];
    }
}

frist タグ (上記の例でHorusは ) がスキャンされた文字列の最初 (location = 0) にある場合、これは失敗します。タグが見つからず、コードがループし続けます。

ただし、文字列を次のように置き換えると:

10年後、ホルスは父オシリスの仇を討った

...すべて機能し、両方のタグが(予想どおり)見つかり、適切に強調表示されます。

何か不足していますか、それとも NSScanner のバグですか?

4

1 に答える 1

2

ドキュメントを参照してください

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

stopString が受信側の最初の文字列である場合、メソッドは NO を返し、stringValue は変更されません。

スキャナは文字列を検出しましたが、そのために文字をスキャンしていないため、NO を返しました。positionその部分はif (result)ブロック内にあるため、コードは変数を増やしません。

ifステートメントを削除すると問題が解決するはずだと思います。スキャナーが stopString を見つけられなかった場合、while条件は失敗し、コードはまったくループに入りません。

于 2012-01-03T20:05:45.243 に答える