Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop enumerateAttribute:inRange:options:usingBlock: from calling my block with nil values

I'm calling the following selector on an existing NSAttributedString with no kCTFontAttributeName ranges:

[attributedString enumerateAttribute:(NSString *) kCTFontAttributeName
                             inRange:NSMakeRange(0, [attributedString length])
                             options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
                          usingBlock:^(id value, NSRange range, BOOL *stop) {
    NSLog(@"Attribute: %@, %@", value, NSStringFromRange(range));
}];

and I get the output below, but I would expect to get no output. Suggestions?

Attribute: (null), {0, 27}
Attribute: (null), {27, 1}
Attribute: (null), {28, 1}
Attribute: (null), {29, 1}
Attribute: (null), {30, 1}
like image 659
Heath Borders Avatar asked Dec 28 '22 03:12

Heath Borders


1 Answers

The short answer? -enumerateAttribute:inRange:options:usingBlock: doesn't do what you (or I, originally) thought it does.

From the name, you might assume it only enumerates over ranges of the receiver that contain the given attribute. This is not the case. It always enumerates over the entire string. It calls the block for each run it encounters. The value passed into the block is set to the value the given attribute for that run. If the current run doesn't contain the given attribute, it passes nil for value.

Thus, for a string that does not contain the given attribute, it will still fire the block, but the value will always be nil. For a string that that is completely covered by the the given attribute (with the same value), you would expect the block to fire once with value being equal to that attribute's value in the string. For a string that is partially covered by the given attribute, you would expect the block to fire multiple times, sometimes with a value of nil, and sometimes with a value equal to that of the attribute.

Hope that helps. It took me a while to look at it from the correct direction, also.

like image 127
jemmons Avatar answered Apr 26 '23 04:04

jemmons