vk.edward.li
vk.edward.li

Reputation: 1949

Core Text loads ALL system fonts into Resident Memory

Whenever I'm using CTFontCreateWithFontDescriptor() (below snippet is referenced from this article)

I found that ALL fonts are mapped, and seems wasted around 20MB.

dispatch_queue_t queue = dispatch_queue_create("font.worker", NULL);
dispatch_async(queue, ^(void) {
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:@"Helvetica" forKey:(id)kCTFontFamilyNameAttribute];
    [attributes setObject:[NSNumber numberWithFloat:36.0f] forKey:(id)kCTFontSizeAttribute];
    CTFontDescriptorRef fontDesc = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)attributes);
    CTFontRef matchingFont = CTFontCreateWithFontDescriptor(fontDesc, 36.0f, NULL);
    CFRelease(matchingFont);
    CFRelease(fontDesc);
});
dispatch_release(queue);

I heard it is fixed in iOS 5, so the question is:

Is it possible to use custom font with Core Text, but load the necessary font only?

enter image description here

Upvotes: 0

Views: 1083

Answers (1)

Cocoanetics
Cocoanetics

Reputation: 8247

Before iOS 5 fixed that CoreText would always load the entire font mapping table the first time you are searching for a font. That happened using font descriptors. If you instatiate the font directly by name then this does not happen.

In DTCoreText on GitHub https://github.com/Cocoanetics/DTCoreText I am working around this by matching bold and italic myself to the font name and then creating the font from that.

A workaround was to instatiate the mapping table load on a background queue. See: http://www.cocoanetics.com/2011/04/coretext-loading-performance/ This workaround is no longer necessary as of iOS 5. I had a Radar open and Apple fixed that.

PS: A mapped file does not use RAM, it is just mapped into the address space for access via pointers. The loading caused another problem, it woukd take 1 sec on device causing a pause if done on main thread.

Upvotes: 3

Related Questions