9
[attributedString enumerateAttributesInRange:range options:NSAttributedStringEnumerationReverse usingBlock:
     ^(NSDictionary *attributes, NSRange range, BOOL *stop) {

         NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
         [mutableAttributes setObject:[NSNumber numberWithInt:1] forKey:@"NSUnderline"];
         attributes = mutableAttributes;

     }];

私はすべての属性をループして、それらに NSUnderline を追加しようとしています。デバッグ時に NSUnderline がディクショナリに追加されているように見えますが、2 回目にループすると削除されます。NSDictionaries の更新中に何か問題がありますか?

4

2 に答える 2

21

ジョナサンの答えは、それがうまくいかない理由をうまく説明しています。これを機能させるには、属性付き文字列にこれらの新しい属性を使用するように指示する必要があります。

[attributedString enumerateAttributesInRange:range options:NSAttributedStringEnumerationReverse usingBlock:
     ^(NSDictionary *attributes, NSRange range, BOOL *stop) {

         NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
         [mutableAttributes setObject:[NSNumber numberWithInt:1] forKey:@"NSUnderline"];
         [attributedString setAttributes:mutableAttributes range:range];

 }];

属性付き文字列の属性を変更するには、それが NSMutableAttributedString である必要があります。

これを行う簡単な方法もあります。NSMutableAttributedString は、addAttribute:value:range:他の属性を変更せずに、特定の属性の値を指定された範囲に設定するメソッドを定義します。コードをこのメソッドへの単純な呼び出しに置き換えることができます (依然として変更可能な文字列が必要です)。

[attributedString addAttribute:@"NSUnderline" value:[NSNumber numberWithInt:1] range:(NSRange){0,[attributedString length]}];
于 2011-07-21T22:03:42.090 に答える
5

辞書のローカル コピーを変更しています。属性付き文字列には、変更を確認する方法がありません。

C のポインターは値によって渡されます (したがって、ポインターが指すものは参照によって渡されます)。そのため、新しい値を に割り当てるattributesと、ブロックを呼び出したコードは、変更されたことを認識しません。変更は、ブロックのスコープ外には伝播しません。

于 2011-07-21T20:42:38.070 に答える