2011-07-23 16 views
3

コードのブロックを取得し、NSAttributedStringNSAttributedString - enumerateAttributesInRangeによってクラッシュが発生しますか?

  • にすべての属性のためにそれを実行enumerateAttributesInRange方法は非同期ボックを呼んでいますか?

OTHR私のアプリがフリーズ取得した後、次のような方法が1本当に素早く2回連続で呼び出されるとき、私はそれを疑問に思って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 
}]; 
} 

答えて

5

アトリビュートされている文字列が列挙されている間に変更しています。私はこれが徹底的に列挙子を混乱させると思います。なぜなら、それが作業している属性文字列は、列挙を開始したときの状態ではないからです。ブロック内では、のみがの属性を収集します。ディクショナリまたは配列内にあるが、それらを修正しての後にの後、つまり列挙が終了した後に文字列に適用する。

つまり、列挙中に呼び出されるブロック内で、属性付き文字列を変更するコードを挿入しないでください。 docsでは、ブロックが適用される範囲内の属性付き文字列を変更できますが、ISTMでは外に出ないように注意する必要があります。私はこれをしません。

0

少し遅れていますが、その後は[self.attributedString beginEditing];を追加し、その後は[self.attributedString endEditing];を追加してクラッシュを解決するようです。

+0

また、nilオブジェクトの辞書キーをテストすることを忘れないでください。 – Stuart

関連する問題