Core Text 将所有系统字体加载到常驻内存中
每当我使用 CTFontCreateWithFontDescriptor()
(以下代码段引用自此 文章)
我发现所有字体都被映射了,并且似乎浪费了大约 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);
我听说它在 iOS 5 中已修复,所以问题是:
是否可以在 Core Text 中使用自定义字体,但仅加载必要的字体?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 iOS 5 修复之前,CoreText 总是会在您第一次搜索字体时加载整个字体映射表。这是使用字体描述符发生的。如果您直接通过名称实例化字体,则不会发生这种情况。
在 GitHub 上的 DTCoreText https://github.com/Cocoanetics/DTCoreText 中,我正在通过匹配粗体来解决此问题我自己将字体名称改为斜体,然后从中创建字体。
解决方法是在后台队列上实例化映射表负载。请参阅:http://www.cocoanetics.com/2011/04/coretext-从 iOS 5 开始,不再需要此解决方法。我打开了 Radar,Apple 修复了该问题。
PS:映射文件不使用RAM,它只是映射到地址空间以通过指针访问。加载导致了另一个问题,如果在主线程上完成,设备上将需要 1 秒,从而导致暂停。
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.