You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CGDataProviderRef释放回调未触发:CGBitmap像素缓冲区无法释放

问题分析与解决

核心原因

你猜的没错,done_callback始终不执行的关键原因就是你创建的Core Graphics对象没有被正确释放。Core Graphics采用手动引用计数机制,你创建的CGImageRef、CGDataProviderRef、CGColorSpaceRef都会持有资源引用,只要这些对象没被销毁,系统就不会触发数据提供者的回调来释放像素缓冲区。

具体修复步骤

  1. 释放创建的中间CG对象
    CGImageCreate会自动持有传入的CGDataProviderRef和CGColorSpaceRef的引用,所以在创建完CGImage后,你可以立即释放这两个对象,避免不必要的内存占用:

    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, width * height * 4, done_callback);
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    CGImageRef image = CGImageCreate(width, height, 8, 32, 4 * width, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
    
    // 释放不再需要的provider和colorSpace
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpaceRef);
    
    return image;
    
  2. 调用方必须释放返回的CGImageRef
    调用SVG_to_CGImage的代码,在使用完返回的CGImageRef后,必须手动调用CGImageRelease()来释放它。只有当CGImage被销毁时,它持有的CGDataProvider才会被释放,进而触发done_callback:

    CGImageRef svgImage = SVG_to_CGImage(svgContent, 200, 200);
    // 这里做渲染、转换UIImage等操作
    CGImageRelease(svgImage); // 执行这行后,done_callback才会被调用
    

额外优化(ARC环境下)

如果是在Objective-C的ARC环境中使用,可以把CGImageRef包装成UIImage,让ARC自动管理内存:

CGImageRef svgImage = SVG_to_CGImage(svgContent, 200, 200);
UIImage *uiImage = [UIImage imageWithCGImage:svgImage];
CGImageRelease(svgImage); // 这里手动释放CGImage,UIImage会持有内部资源
// 当uiImage被ARC销毁时,会自动释放对应的CG资源,触发done_callback

内容的提问来源于stack exchange,提问作者Charlie Skilbeck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 19:40:31