美文网首页移动开发俱乐部
iOS 自定义字体内存泄漏( leak cycles)

iOS 自定义字体内存泄漏( leak cycles)

作者: 恩莱客 | 来源:发表于2018-03-12 16:28 被阅读9次

问题描述:工程中内存管理采用ARC方式,我们在使用自定义字体时内存存在持续增加不释放问题,Xcode Debug显示在使用字体时,Memory升降不是平衡的(切换界面),造成内存逐渐累积,而我们工程中使用自定义字体的地方非常多,内存飙升的可怕。使用Instrument中的leak工具检测(如下图),FontFamily 方法中存在循环引用问题。

leak检测.png

leak cycles方法:

- (NSString *)fontFamilyWithFontPath{
   NSString *fontPath = [NSHomeDirectory() stringByAppendingString:[NSString
             stringWithFormat:@"/Documents/%@.ttf", _cssInfo.fontFamily]];
     NSData *dynamicFontData = [NSData dataWithContentsOfFile:fontPath];
    if (!dynamicFontData) {
        return@"";
    }
    CFErrorRef error = nil;
    CGDataProviderRef providerRef = CGDataProviderCreateWithCFData((__bridge CFDataRef)dynamicFontData);
    if (!providerRef) {
        CGDataProviderRelease(providerRef);
        return @"";
    }
    [UIFont familyNames];
    CGFontRef newFont = CGFontCreateWithDataProvider(providerRef);
    if (!newFont) {
        CGFontRelease(newFont);
        CGDataProviderRelease(providerRef);
        return @"";
    }
    if (!CTFontManagerRegisterGraphicsFont(newFont, &error)) {
        //注册失败
        CFStringRef errorDescription = CFErrorCopyDescription(error);
        CFRelease(errorDescription);
    }
    NSString *newFamilyName = CFBridgingRelease(CGFontCopyPostScriptName(newFont));
    CGDataProviderRelease(providerRef);
    CGFontRelease(newFont);
}

代码调整:去掉了dataWithContentsOfFile:获取data过程,而是直接使用URL获取字体数据。

  NSString *fontPath = [NSHomeDirectory() stringByAppendingString:[NSString
             stringWithFormat:@"/Documents/%@.ttf", _cssInfo.fontFamily]];
    if (!fontPath) {
        return @"";
    }
    //调整位置
    NSURL *fontUrl = [NSURL fileURLWithPath:fontPath];
    CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);
    if (!fontDataProvider) {
        CGDataProviderRelease(fontDataProvider);
        return @"";
    }
    [UIFont familyNames];
    CGFontRef fontRef = CGFontCreateWithDataProvider(fontDataProvider);
    if (!fontRef) {
        CGDataProviderRelease(fontDataProvider);
        CGFontRelease(fontRef);
        return @"";
    }
    CGDataProviderRelease(fontDataProvider);
    CTFontManagerUnregisterGraphicsFont(fontRef,nil);
    CTFontManagerRegisterGraphicsFont(fontRef, NULL);
    NSString *newFamilyName = CFBridgingRelease(CGFontCopyPostScriptName(fontRef));
    CGFontRelease(fontRef);

经过调整后,内存使用恢复正常。

相关文章

  • iOS 自定义字体内存泄漏( leak cycles)

    问题描述:工程中内存管理采用ARC方式,我们在使用自定义字体时内存存在持续增加不释放问题,Xcode Debug显...

  • 【Android测试】内存泄漏检测 LeakCanary

    什么是内存泄漏和内存溢出?内存泄漏有什么危害?LeakCanary检测内存泄漏? 内存泄漏(Memory Leak...

  • 内存泄漏

    什么是内存泄漏引起内存泄漏的原因野指针,空指针,僵尸对象 1.什么是内存泄漏 内存泄漏(Memory Leak)是...

  • A1_内存泄漏(循环引用)

    一、什么是内存泄漏,在 Obj-C 中如何检测内存泄漏? “内存泄漏(Memory Leak)是指程序中己动态分配...

  • 内存泄漏和内存溢出的区别与解决方式

    内存泄漏(memory leak ) 是指程序在申请内存后,无法释放已申请的内存空间就造成了内存泄漏,一次内存泄漏...

  • android内存泄漏快速解决

    明白原理 一般内存泄漏(traditional memory leak)的原因是:忘记释放分配的内存 逻辑内存泄漏...

  • 非OC对象内存泄漏处理

    内存泄漏提示: Potential leak of an object stored into 'cs' 如下图 ...

  • 11.2-1 Bitmap2 OOM

    简介 Out Of Memory(内存溢出):占用内存超出系统分配内存; memory leak(内存泄漏):占用...

  • Android内存泄漏和内存溢出详解

    什么是内存泄漏和内存溢出 内存泄漏(Memory Leak):指的是程序在申请内存空间之后,无法释放已占有的空间,...

  • 内存泄漏

    内存问题的可能情况 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏...

网友评论

    本文标题:iOS 自定义字体内存泄漏( leak cycles)

    本文链接:https://www.haomeiwen.com/subject/uksttftx.html