NSAttributedString - enumerateAttributesInRange导致崩溃?

时间:2011-07-23 00:01:15

标签: iphone objective-c nsattributedstring

方法enumerateAttributesInRange获取代码块并为NSAttributedString

中的每个属性执行代码
  • 是否异步调用bock?

当以下方法在我的应用程序被冻结之后连续两次被调用时,我很想知道它是因为enumerateAttributesInRange异步运行代码块,所以2个线程试图在同一时间修改我的AttributedString时间。

- (void) doSomething
{
   //following line works fine
   [self doSomethingwithAttributedString];

   //following line works fine
   [self doSomethingwithAttributedString];
   [self performSelector:@selector(doSomethingwithAttributedString) withObject:nil afterDelay:1];

   //following crashes
    [self doSomethingwithAttributedString];
    [self doSomethingwithAttributedString];
}

- (void)doSomethingwithAttributedString
{
   [self.attributedString enumerateAttributesInRange:_selectedRange options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:
 ^(NSDictionary *attributes, NSRange range, BOOL *stop) {

          // Here I modify the dictionary and add it back to my attributedString
 }];
}

2 个答案:

答案 0 :(得分:5)

您在枚举时修改属性字符串。我打赌这完全混淆了枚举器,因为它正在处理的属性字符串不在它开始枚举时的状态。在该块中,只有收集属性,例如在字典或数组中,但修改它们并将它们应用到字符串之后,即在枚举完成后。

换句话说:不要将修改属性字符串的代码放在枚举期间调用的块中。 docs表示您可以修改块适用范围内的属性字符串,但ISTM必须非常小心,不要出门。我不会这样做。

答案 1 :(得分:0)

我有点晚了,但之前添加[self.attributedString beginEditing];和之后[self.attributedString endEditing];似乎可以解决崩溃问题。