Objective C - Change all attributes in NSAttributedString?
[attributedStr开发者_如何学运维ing 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;
}];
I am trying to loop through all attributed and add NSUnderline to them. when debugging it seems like NSUnderline is added to the dictionary, but when i loop for the second time they are removed. Am I doing anything wrong while updating NSDictionaries?
Jonathan's answer does a good job of explaining why it doesn't work. To make it work, you need to tell the attributed string to use these new attributes.
[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];
}];
Changing the attributes of an attributed string requires that it is a NSMutableAttributedString.
There is also an easier way to do this. NSMutableAttributedString defines the addAttribute:value:range:
method, which sets the value of a specific attribute over the specified range, without changing other attributes. You can replace your code with a simple call to this method (still requiring a mutable string).
[attributedString addAttribute:@"NSUnderline" value:[NSNumber numberWithInt:1] range:(NSRange){0,[attributedString length]}];
You're modifying a local copy of the dictionary; the attributed string does not have any way to see the change.
Pointers in C are passed by value (and thus what they point to is passed by reference.) So when you assign a new value to attributes
, the code that called the block has no idea you changed it. The change does not propagate outside of the block's scope.
精彩评论