I have a very weird problem with core text, which sometimes randomly and sometimes reproducibly crashes my application. I use it to lay out and render a couple of pages. I do th
I've asked some of the engineers during WWDC whether they know the issue. The answer: YES. And there are in fact some problems in the type subsystem. They might be doing a fix some day, but for now all that is left to do is to sequentialize all text layout. :(
Everyone: PLEASE FILE BUGS!
Here is what the documentation says:
Multicore Considerations: All individual functions in Core Text are thread safe. Font objects (CTFont, CTFontDescriptor, and associated objects) can be used by simultaneously by multiple operations, work queues, or threads. However, the layout objects (CTTypesetter, CTFramesetter, CTRun, CTLine, CTFrame, and associated objects) should be used in a single operation, work queue, or thread.
So I guess there is no way around serialising calls to CTFramesetterCreateWithAttributedString
.
CoreText takes a while to initialize the font lookup table when you use it for the first time. I imagine you might be able to get rid of your problem by first triggering a loading of this table before going to multiple threads.
See http://www.cocoanetics.com/2011/04/coretext-loading-performance/ for a method how.
fix from me :-) no crash anymore
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:aText];
[attributedString addAttribute:(id)kCTFontAttributeName value:(id)aFontRef range:NSMakeRange(0, [aText length])];
CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString);
CFMutableAttributedStringRef attributedStringRef = CFAttributedStringCreateMutable(nil, 0);
CFAttributedStringBeginEditing(attributedStringRef);
CFAttributedStringReplaceString(attributedStringRef, CFRangeMake(0, 0), (CFStringRef)aText);
CFAttributedStringSetAttribute(attributedStringRef, CFRangeMake(0, aText.length), kCTFontAttributeName, aFontRef);
CFAttributedStringEndEditing(attributedStringRef);
CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString(attributedStringRef);
Please make sure you're retaining the framesetter before reopening it. This is REALLY not meant to be used asynchronous before 4.0!
CFRelease(framesetter);
Could you also provide the Version of Xcode & iOS you're working with?