C-如何避免使用CTFontCreateWithGraphicsFont的内存泄漏



我已经将泄漏问题减少到了易于编译的代码,该代码在CTFontCreateWithGraphicsFont使用和发布后显示了ct_font,将留下额外的cg_font参考。这是一个内部的Apple Ref计数问题,还是我缺少一些内容,例如必须倍发布cg_font或更改版本的顺序?谢谢。

#include <stdio.h>
#include <stdlib.h>
#include <ApplicationServices/ApplicationServices.h>
int main(int argc, char **argv) {
    FILE *f = fopen("/Library/Fonts/Tahoma.ttf", "rb");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    fseek(f, 0, SEEK_SET);
    
    char* font = (char*)malloc(fsize);
    fread(font, fsize, 1, f);
    fclose(f);
    
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, font, fsize, NULL);
    CGFontRef cg_font = CGFontCreateWithDataProvider(provider);
    CTFontRef ct_font = CTFontCreateWithGraphicsFont(cg_font, 36., NULL, NULL);
    CGDataProviderRelease(provider);
    //
    
    CFRelease(ct_font);
    CFRelease(cg_font);
    
    printf("ct_font: %dncg_font: %dn", (int)CFGetRetainCount(ct_font), (int)CFGetRetainCount(cg_font));
    free(font);
    
    return 0;
}

编译和运行后的结果:

ct_font:-1

cg_font:1

CGFont的保留发生在TInMemoryBaseFont构造函数中:

#0  0x00007fff8928e4d0 in CFRetain ()
#1  0x00007fff86472906 in TInMemoryBaseFont::TInMemoryBaseFont(CGFont*) ()
#2  0x00007fff864728b8 in CTFontDescriptor::CTFontDescriptor(CGFont*, is_inmemory_t const&) ()
#3  0x00007fff8646cb30 in TDescriptorSource::CopyDescriptor(CGFont*, __CFDictionary const*) const ()
#4  0x00007fff8646c99a in TFont::InitDescriptor(CGFont*, __CTFontDescriptor const*) ()
#5  0x00007fff8646c7b4 in TFont::TFont(CGFont*, double, CGAffineTransform const*, __CTFontDescriptor const*) ()
#6  0x00007fff8646c775 in CTFontCreateWithGraphicsFont ()

释放CTFont时与发布不匹配,可能是因为TInMemoryBaseFont破坏者从未被调用(出于未知原因)。

这不是解决方案,但可能会帮助某人进一步调试问题。

最新更新