方法enumerateAttributesInRange
获取代码块并为NSAttributedString
当以下方法在我的应用程序被冻结之后连续两次被调用时,我很想知道它是因为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
}];
}
答案 0 :(得分:5)
您在枚举时修改属性字符串。我打赌这完全混淆了枚举器,因为它正在处理的属性字符串不在它开始枚举时的状态。在该块中,只有收集属性,例如在字典或数组中,但修改它们并将它们应用到字符串之后,即在枚举完成后。
换句话说:不要将修改属性字符串的代码放在枚举期间调用的块中。 docs表示您可以修改块适用范围内的属性字符串,但ISTM必须非常小心,不要出门。我不会这样做。
答案 1 :(得分:0)
我有点晚了,但之前添加[self.attributedString beginEditing];
和之后[self.attributedString endEditing];
似乎可以解决崩溃问题。