MultiThread Crashのsizewithfont!
-
30-09-2019 - |
質問
sizewithfontがmultithreadでクラッシュした、これはデバッグ情報です。
1 0x00a0df8e in icu::RuleBasedBreakIterator::handleNext
2 0x00a0daff in icu::RuleBasedBreakIterator::next
3 0x00a0d174 in icu::RuleBasedBreakIterator::following
4 0x35879719 in WebCore::nextBreakablePosition
5 0x3587842a in -[NSString(WebStringDrawing) _web_drawInRect:withFont:ellipsis:alignment:lineSpacing:includeEmoji:measureOnly:]
6 0x35877da3 in -[NSString(WebStringDrawing) _web_sizeInRect:withFont:ellipsis:lineSpacing:]
7 0x3090d238 in -[NSString(UIStringDrawing) sizeWithFont:constrainedToSize:lineBreakMode:lineSpacing:]
8 0x3090cee3 in -[NSString(UIStringDrawing) sizeWithFont:constrainedToSize:lineBreakMode:]
これで、NSLockオブジェクトを使用してエラーを解きます。この関数を使用する前に、このオブジェクトをロックし、その後ロックを解除します
しかし、もっと良い解決策がなければならないと思います!
そして、このエラーは、両方の2つのスレッドのこの関数のnsStringオブジェクトがマルチラインテキストである場合にのみ表示されることがわかりました。
解決
原則として、別のスレッドからuikitメソッド[1]を呼び出すべきではありません。あなたがロックを取っているかどうかは関係ありません、これは非スターターです。
マルチスレッドアプリケーションを使用している場合、UIKITオブジェクトがメインスレッドで実行されるコードを確認する必要があります。これは、PerformSelectorOnMainThreadを使用することで実現されます。
またはMonotouch:foo.invokeonmainthread(delegate {your_code_here});
1] iOS 4.0では、ほんの一握りのAPIのためにルールがリラックスしています。
他のヒント
フォーマットしてください。
オブジェクトの周りにランダムロックを配置することでマルチスレッドの問題を「解決」することは決して正しい答えではありません。これまでに。マルチスレッドには、アプリケーションの体系的な設計が必要です。
ロックが問題を「修正」する場合、あなたがロックしたものと状況を評価するためにどのように重要であるかを示します。
さらにいくつかの症状が役立つでしょう。特にコード。質問のコードは非常に便利です。
証拠がないことを考えると、私はあなたが別のスレッドのサイズをつかもうとしながら、あるスレッドの文字列を変異させていることを賭けています。または、オブジェクトは別のスレッドを使用しながら、1つのスレッドでリリースされています。または、スレッドセーフではない二次スレッドからオブジェクトを操作しています。
performselectoronmainthread:with object:waituntildone:正しいと思います。
以前は、操作を使用してテキストサイズを計算し、メインスレッドで採用されたwaituntilalloperationsは、操作の返品を待つために使用します。
ただし、PerformSelectorOnMainThread:withObject:waituntildoneを操作で使用し、waituntildoneパラメーターをyesに設定する場合(結果が必要なため)
メインスレッドが刺されます
そのため、今ではwaituntilalloperationSarefinishedを削除し、非同期オブジェクトを使用して、前のものが停止するまで操作が開始されないようにします
[md removeAllObjects];
[md setObject:subString forKey:@"text"];
[md setObject:[NSNumber numberWithInt:view_w ] forKey:@"width"];
[md setObject:[NSNumber numberWithInt:height_left + font_h ] forKey:@"height"];
[self performSelectorOnMainThread:
@selector(calculateTextRegion:)
withObject:md
waitUntilDone:YES];
CGSize stringSize = textRegion;