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

PDFKit生成多图片PDF内存不释放致崩溃求优化方案

解决PDFKit生成PDF时内存无法释放的问题

问题根源

  1. 递归调用会导致每一层函数上下文堆积在栈中,加上PDFDocument一直持有所有生成的PDFPage,内存会持续飙升直到崩溃。
  2. 当前的autoreleasepool只包裹了部分逻辑,没有覆盖单张图片转PDFPage的完整生命周期,没法及时释放临时对象的内存。
  3. 直接用UIImage生成PDFPage,高清大图会一次性占用大量内存,未做针对性内存优化。

修复方案

  1. 替换递归为迭代循环:避免栈内存堆积,同时更灵活控制每一步的内存释放。
  2. 给单张图片处理单独加autoreleasepool:确保每张图片转完PDFPage后,临时对象立即被释放。
  3. 写完PDF后立即销毁PDFDocument:让系统及时回收所有页面占用的内存。
  4. 优化图片内存占用:将UIImage转成CGImage,或对大图进行压缩后再处理。

修改后的代码示例

func createPdf(from imageData: [UIImage], name: String) {
    let pdfDocument = PDFDocument()
    let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    var outputURL = documentDirectory.appendingPathComponent("PDFReader")
    
    // 先创建存储目录
    do {
        try FileManager.default.createDirectory(at: outputURL, withIntermediateDirectories: true)
        outputURL = outputURL.appendingPathComponent("\(name).pdf")
    } catch {
        print(error.localizedDescription)
        return
    }
    
    // 迭代处理每张图片,每张单独用autoreleasepool包裹
    for (index, image) in imageData.enumerated() {
        autoreleasepool {
            // 转CGImage减少内存占用,避免UIImage的额外解码开销
            guard let cgImage = image.cgImage else { return }
            let pdfPage = PDFPage(image: UIImage(cgImage: cgImage))!
            pdfDocument.insert(pdfPage, at: index)
        }
    }
    
    // 写入PDF操作单独加autoreleasepool
    autoreleasepool {
        do {
            try pdfDocument.write(to: outputURL)
            print("Write Successfully")
        } catch {
            print(error.localizedDescription)
        }
    }
    
    // 手动清空页面并置空,让PDFDocument立即被系统回收
    pdfDocument.removeAllPages()
}

额外优化建议

  • 如果图片是从本地文件读取的,尽量直接用Data或CGImageSource加载,避免UIImage自动解码带来的额外内存占用。
  • 对超大尺寸图片,可以先按PDF标准页面尺寸(如A4)等比例缩放,减少单页PDF的内存消耗。

内容的提问来源于stack exchange,提问作者Muhammad Bilal Raza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:10:29