2012-01-16 13 views
1

私はCTTypesetterを使用して、サーバーからJSONから読み込んだメッセージをレイアウトしています。しかし、特定の特定のメッセージではクラッシュします。つまり、以下のようなユニコード文字は異常です。CTTypesetterが奇妙なUnicode文字でクラッシュする

CFAttributedStringRef attrString = CFAttributedStringCreate(NULL, @"❝We  must  learn  to  live  together  as  brothers  or  perish  together  as  fools❞ ~Martin Luther King Jr. #HappyMLKDay", nil); 
CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString(attrString); 

これは、以下のスタックトレースでクラッシュします。

#0 0x33a4684e in TBaseFont::CopyCharacterSet() const() 
#1 0x33a2c0d4 in CompareCharSet(__CFCharacterSet const*, TBaseFont const*)() 
#2 0x33a2f03e in TDescriptorSource::CopyDescriptorsForRequestFromArray(__CFArray const*, __CFDictionary const*, long (*)(void const*, void const*, void*), void*, unsigned long, bool) const() 
#3 0x33a2ead0 in TDescriptorSource::CopyDescriptorsForRequest(__CFDictionary const*, __CFSet const*, long (*)(void const*, void const*, void*), void*, unsigned long) const() 
#4 0x33a2e624 in TDescriptorSource::CopyDescriptorForRequest(__CFDictionary const*, __CFSet const*, long (*)(void const*, void const*, void*), void*, unsigned long) const() 
#5 0x33a2e532 in TDescriptorSource::CopySystemWideFallbackDescriptor(CGFont*, unsigned short const*, long) const() 
#6 0x33a2e79c in TDescriptorSource::CopySystemWideFallbackDescriptor(CGFont*, __CFString const*, CFRange) const() 
#7 0x33a27c78 in TFontCascade::CreateSystemWideFallback(__CTFont const*, __CFString const*, CFRange) const() 
#8 0x33a27b28 in TFontCascade::CreateFallback(__CTFont const*, __CFString const*, CFRange) const() 
#9 0x33a185ec in TGlyphEncoder::AppendUnmappedCharRun(CTRun*, CFRange, CFRange, TGlyphList<TDeletedGlyphIndex>&, TGlyphList<TDeletedGlyphIndex>&, TFontCascade const&, bool)() 
#10 0x33a184b8 in TGlyphEncoder::RunUnicodeEncoderRecursively(CTRun*, adopted_t const&, CFRange, TGlyphList<TDeletedGlyphIndex>&, TGlyphList<TDeletedGlyphIndex>&, TFontCascade const*, bool)() 
#11 0x33a186e4 in TGlyphEncoder::AppendUnmappedCharRun(CTRun*, CFRange, CFRange, TGlyphList<TDeletedGlyphIndex>&, TGlyphList<TDeletedGlyphIndex>&, TFontCascade const&, bool)() 
#12 0x33a184b8 in TGlyphEncoder::RunUnicodeEncoderRecursively(CTRun*, adopted_t const&, CFRange, TGlyphList<TDeletedGlyphIndex>&, TGlyphList<TDeletedGlyphIndex>&, TFontCascade const*, bool)() 
#13 0x33a1824c in TGlyphEncoder::RunUnicodeEncoder(CTRun*, adopted_t const&, CFRange, TGlyphList<TDeletedGlyphIndex>&, TFontCascade const*)() 
#14 0x33a07a1a in TGlyphEncoder::EncodeChars(CFRange, TAttributes const&, TGlyphList<TDeletedGlyphIndex>&, TGlyphEncoder::Fallbacks)() 
#15 0x33a0665c in TTypesetterAttrString::Initialize(__CFAttributedString const*)() 
#16 0x33a064a4 in TTypesetterAttrString::TTypesetterAttrString(__CFAttributedString const*)() 
#17 0x33a06418 in TTypesetterAttrString::TTypesetterAttrString(__CFAttributedString const*)() 
#18 0x33a1e78c in CTTypesetterCreateWithAttributedString() 

は、しかし私はそれが正常に動作し、この環境の中で、試してみて、クラッシュを再現する空のプロジェクトを作成しました。

ドキュメントでは、これは言っている:

マルチコアに関する注意事項:コア・テキストのすべての個々の機能は スレッドセーフですが。フォントオブジェクト(CTFont、CTFontDescriptor、および対応する オブジェクト)は、複数の操作、作業 キュー、またはスレッドによって同時に使用できます。ただし、レイアウトオブジェクト(CTTypesetter、 CTFramesetter、CTRun、CTLine、CTFrame、および関連オブジェクト)は、 を単一の操作、作業キュー、またはスレッドで使用する必要があります。

この目的のために、これを解決するために、すべての種類のスレッド、つまり数少ないdispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ...)を取り出しました。 20を超えるKSLOCプロジェクトを掘り起こす以外に、私が解決しようとしていることが他に何か分かりません。

シミュレータではなく、実際のiPad(5.0と5.1の両方でテストされた3つのモデルすべて)がクラッシュするだけです。

これを解決するにはどうすればよいですか?私は、できるだけ多くのフォールバックフォントをそれらにマージした状態で、Helveticaの修正版を埋め込むことに頼っていますが、それは最適な解決策ではありません。


これは1月から私が狂ったようになってきたのがわかるように、どんな入力も非常に感謝しています!

答えて

0

私はちょうどそれを解決しました。

私はinfo.plistで43フォントを参照していました。すべてが有効で、すべて私のリソースバンドルにotfまたはttfが入っていました。私はちょうど削除し、それは動作し始めた。

くそApple bug。

+1

他の人のバグを呪うよりも、再現性のある最小のケースを作成し、[レポート](https://bugreport.apple.com/)を修正して修正してください。 – marko