3

メソッドenumerateAttributesInRangeはコードのブロックを取得し、すべての属性に対してそれを実行しますNSAttributedString

  • ブロックを非同期で呼び出しますか?

次のメソッドが 2 回続けて呼び出されると、アプリがフリーズした後、非常に迅速に 1 になります。これは、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
 }];
}
4

2 に答える 2

5

列挙中に属性付き文字列を変更しています。これは列挙子を完全に混乱させるに違いありません。なぜなら、列挙子が作業している属性付き文字列は、列挙を開始したときの状態ではないからです。ブロックでは、辞書や配列などの属性のみを収集しますが、それらを変更して後で文字列に適用します。つまり、列挙が終了した後です。

つまり、列挙中に呼び出されるブロック内の属性文字列を変更するコードを配置しないでください。ドキュメントには、ブロックが適用される範囲内で属性付きの文字列を変更できると書かれていますが、ISTM では外に出ないように細心の注意を払う必要があります。私はこれをしません。

于 2011-07-23T01:26:27.373 に答える
0

少し遅れましたが、[self.attributedString beginEditing];前後に追加すると[self.attributedString endEditing];クラッシュが解決するようです。

于 2012-10-27T08:39:26.467 に答える