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 已添加到字典中,但是当我第二次循环时,它们被删除了。更新 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 回答