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

UITableViewCell中从Base64字符串创建图片时崩溃问题排查

排查与解决UIImage(data:)引发的崩溃问题

首先咱们聚焦崩溃点:Crashlytics指向if let img = UIImage(data: image as Data)这一行。虽然UIImage(data:)通常只会返回nil而不会崩溃,但结合你的代码和场景,我整理了可能的原因及对应的解决方案:

可能的崩溃原因

  1. 无效的图片数据:虽然fromBase64Img()成功解码出NSData,但该数据本身并非有效的图片格式(比如损坏、截断,或者根本不是图片数据),触发了UIImage底层初始化逻辑的崩溃。
  2. 不规范的Base64字符串:emp.profilepicture的Base64字符串可能包含多余的空格、换行符或其他无效字符,你的解码方法没报错,但解码出的Data存在隐性损坏。
  3. 极端场景:空Data:解码出的NSData是空的,虽然大部分iOS版本处理空Data不会崩溃,但个别版本可能存在底层bug引发崩溃。

分步解决方案

1. 优化Base64解码逻辑,兼容不规范字符串

你的fromBase64Img()用了默认解码选项,无法处理带多余字符的Base64字符串。修改解码选项并改用Swift原生Data类型,更符合现代开发习惯:

extension String {
    func fromBase64Img() -> Data? {
        // 忽略Base64中的无效字符(如换行、空格)
        guard let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters) else {
            return nil
        }
        // 额外过滤空Data,避免无效数据流入后续逻辑
        return data.isEmpty ? nil : data
    }
}

2. 强化UIImage初始化的防护逻辑

在初始化UIImage前先验证Data有效性,同时添加日志方便定位问题数据:

let item = audits[indexPath.row]
if let emp = Helper_Employee.getEmployee(id: item.auditor){
    cell.nameLbl.text = "\(emp.surname), \(emp.firstname) - \(item.auditnum)"
    
    if let imageData = emp.profilepicture.fromBase64Img() {
        // 先检查Data长度,排除空数据
        guard !imageData.isEmpty else {
            cell.empImg.image = #imageLiteral(resourceName: "ic_blank_employee")
            return
        }
        
        // 用autoreleasepool包裹,避免内存峰值引发的潜在问题
        autoreleasepool {
            if let img = UIImage(data: imageData) {
                cell.empImg.image = img
            } else {
                // 记录日志,方便定位有问题的员工数据
                print("Failed to create image for employee ID: \(emp.id), audit num: \(item.auditnum)")
                cell.empImg.image = #imageLiteral(resourceName: "ic_blank_employee")
            }
        }
    } else {
        cell.empImg.image = #imageLiteral(resourceName: "ic_blank_employee")
    }
} else {
    cell.empImg.image = #imageLiteral(resourceName: "ic_blank_employee")
    cell.nameLbl.text = "No Employee"
}

3. 后端数据排查(可选但重要)

如果上述防护仍无法完全避免崩溃,建议排查后端返回的profilepicture字段:

  • 检查是否存在损坏的Base64字符串
  • 验证该字段对应的原始图片是否为iOS支持的格式(如JPEG、PNG)
  • 确保Base64字符串没有被截断或篡改

4. 性能优化(额外建议)

Base64解码和图片初始化是耗时操作,建议移至后台线程执行,避免阻塞主线程导致界面卡顿:

// 在cellForRow中启动后台任务
DispatchQueue.global(qos: .background).async {
    guard let emp = Helper_Employee.getEmployee(id: item.auditor),
          let imageData = emp.profilepicture.fromBase64Img(),
          !imageData.isEmpty,
          let img = UIImage(data: imageData) else {
        DispatchQueue.main.async {
            cell.empImg.image = #imageLiteral(resourceName: "ic_blank_employee")
        }
        return
    }
    DispatchQueue.main.async {
        // 确保cell仍在屏幕上,避免复用问题
        guard indexPath == tableView.indexPath(for: cell) else { return }
        cell.empImg.image = img
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:15:45