在 iPhone 上通过 CoreText 使用带有某些字体的 Unicode 文本时出现内存泄漏
我在 iPhone 上遇到了一些有趣的 CoreText 问题,在某些情况下会导致内存泄漏。
我在文档和互联网上到处查看,似乎没有人遇到同样的问题。然而,情况可能比较特殊(见下文)。
不管怎样,经过大量缩小范围后,我设法得到了这个重现案例:
void leakTest(NSString* fontname, NSString* text)
{
NSDictionary* descriptorAttr = [NSDictionary dictionaryWithObjectsAndKeys:
fontname, (const NSString*)kCTFontFamilyNameAttribute, nil];
CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)descriptorAttr);
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, 0, nil);
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
(id)font, (const NSString*)kCTFontAttributeName, nil];
CFRelease(descriptor);
CFRelease(font);
NSMutableAttributedString* string = [[NSMutableAttributedString alloc] initWithString:text];
[string setAttributes:dict range:NSMakeRange(0, string.length)];
CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString((CFMutableAttributedStringRef)string);
CFRelease(typesetter);
[string release];
}
根据字体和文本,根据泄漏工具,这可能会也可能不会泄漏 - 各种/众多的东西,但绝对看起来与字体和字体描述符相关。
这些可能是由以下原因引起的:
const char* unicodeText = "Ernle\310\235e"; // "Ernleȝe" if your editor groks unicode
NSString* textLeaky = [NSString stringWithUTF8String:unicodeText];
NSString* textNormal = @"Hello World";
leakTest(@"Courier", textNormal); // This doesn't leak
leakTest(@"Courier", textLeaky); // This does leak
leakTest(@"Arial", textLeaky); // This doesn't leak with this font?
显然,我注释掉了,以便留下一个泄漏测试调用来使用泄漏工具进行测试!
因此,带有不寻常但完全合法的 unicode 字符的字符串会导致一种字体泄漏,但不会导致另一种字体泄漏。
我的代码是否有问题,而我碰巧使用 Arial “侥幸逃脱”?我想知道是否可能存在某种字体缓存导致了明显的泄漏,但操作系统或其他任何东西实际上都可以正常处理它。
希望可以帮到大家!
I'm having some interesting issues with CoreText on iPhone, causing memory leaks in certain circumstances.
I've looked everywhere in the documentation and across the internet and no-one seems to be getting the same issue. However, the circumstances are perhaps special (see below).
Anyway, after a lot of narrowing down, I managed to get this repro case:
void leakTest(NSString* fontname, NSString* text)
{
NSDictionary* descriptorAttr = [NSDictionary dictionaryWithObjectsAndKeys:
fontname, (const NSString*)kCTFontFamilyNameAttribute, nil];
CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)descriptorAttr);
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, 0, nil);
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
(id)font, (const NSString*)kCTFontAttributeName, nil];
CFRelease(descriptor);
CFRelease(font);
NSMutableAttributedString* string = [[NSMutableAttributedString alloc] initWithString:text];
[string setAttributes:dict range:NSMakeRange(0, string.length)];
CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString((CFMutableAttributedStringRef)string);
CFRelease(typesetter);
[string release];
}
Depending on the font and text, this may or may not leak according to the Leaks tool - various/numerous things but definitely seeming font and font descriptor related.
These can be caused as follows:
const char* unicodeText = "Ernle\310\235e"; // "Ernleȝe" if your editor groks unicode
NSString* textLeaky = [NSString stringWithUTF8String:unicodeText];
NSString* textNormal = @"Hello World";
leakTest(@"Courier", textNormal); // This doesn't leak
leakTest(@"Courier", textLeaky); // This does leak
leakTest(@"Arial", textLeaky); // This doesn't leak with this font?
Obviously I commented out so as to leave one leakTest call to test with the Leaks tool!
So, the string with an unusual but perfectly legal unicode character in causes a leak with one font but not the other.
Is there something wrong in my code and I happen to be "getting away with it" with Arial? I wondered whether there may be some kind of font caching that was causing the apparent leak but the OS or whatever is actually all handling it okay.
Hope you can help folks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尽管被泄漏的对象是 CTFont,但我敢打赌 NSMutableAttributedString 正在泄漏。尝试添加一个
@"bogus"
属性,例如一个空的NSData
对象,看看它是否也被泄漏。Although the object being leaked is a
CTFont
, I would betNSMutableAttributedString
is doing the leaking. Try adding a@"bogus"
attribute with, say, an emptyNSData
object and see if it is also leaked.看看这段代码(没有内存泄漏),我使用不同的字体和 unicode 文本。
当我使用 (CFMutableAttributedStringRef) 字符串构造时出现内存泄漏。
我认为你必须使用 CFAttributedStringCreateMutable() 来消除泄漏。
look at this code (no memory leaks) and I use different fonts and unicode text.
There were memory leaks when I use (CFMutableAttributedStringRef)string counstruction.
I think you have to use CFAttributedStringCreateMutable() to remove leaks.