停止 enumerateAttribute:inRange:options:usingBlock: 使用 nil 值调用我的块

发布于 2024-10-09 18:04:24 字数 711 浏览 0 评论 0原文

我在没有 kCTFontAttributeName 范围的现有 NSAttributedString 上调用以下选择器:

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

我得到下面的输出,但我希望不会得到任何输出。建议?

Attribute: (null), {0, 27}
Attribute: (null), {27, 1}
Attribute: (null), {28, 1}
Attribute: (null), {29, 1}
Attribute: (null), {30, 1}

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}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趁微风不噪 2024-10-16 18:04:25

简短的回答? -enumerateAttribute:inRange:options:usingBlock: 并没有按照您(或我最初)的想法进行操作。

从名称来看,您可能会假设它枚举包含给定属性的接收器范围。事实并非如此。它总是枚举整个字符串。它为它遇到的每个运行调用块。传递到块中的 value 设置为该运行的给定属性的值。如果当前运行不包含给定属性,则会传递 nil 作为 value

因此,对于不包含给定属性的字符串,它仍然会触发该块,但value将始终为nil。对于完全被给定属性(具有相同值)覆盖的字符串,您希望该块触发一次,且 value 等于该属性在字符串中的值。对于部分被给定属性覆盖的字符串,您会期望该块会触发多次,有时使用 valuenil,有时使用 value 等于属性的值。

希望有帮助。我也花了一段时间才从正确的方向看它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文