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

Swift应用后台AES加密耗时过长无法完成问题排查

问题原因分析及解决方案

核心原因

  • 无意义的信号量操作加剧后台线程阻塞
    你代码里的DispatchSemaphore完全是多余且逻辑错误的:创建初始值为0的信号量后立刻调用signal(),紧接着又wait(),这两行代码除了浪费线程调度资源外没有任何作用。前台环境下系统线程调度优先级高,这个无效操作不会引发明显问题,但后台环境中系统对线程资源管控更严格,这种无意义的等待会增加线程被系统挂起的概率。

  • iOS后台CPU时间限制
    iOS应用进入后台后,系统会大幅限制应用的CPU使用权限,普通线程会被暂停执行,直到应用回到前台。如果你的加密操作没有通过后台任务断言申请延长后台执行时间,系统会直接暂停加密所在的线程,导致任务停滞。

  • 加密库的线程执行环境依赖
    你使用的AES加密库(大概率是CryptoSwift)的同步加密方法在当前线程执行,如果当前线程是主线程,后台时主线程会被系统强制挂起;如果是普通后台线程,同样会因为系统的后台资源限制而被暂停。

修复方案

  1. 移除无效的信号量代码
    直接删掉这三行无意义的信号量操作:

    let semaphore = DispatchSemaphore(value: 0)
    semaphore.signal()
    semaphore.wait()
    
  2. 申请后台任务权限以延长执行时间
    如果需要在后台完成加密,必须通过UIApplication的后台任务断言来申请额外的执行时间:

    func crypt(dados: String, sistema: String, completion: @escaping (String) -> Void) {
        var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
        backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "AES加密任务") {
            // 任务超时或系统强制结束时的清理操作
            UIApplication.shared.endBackgroundTask(backgroundTaskID)
            backgroundTaskID = .invalid
        }
        
        DispatchQueue.global(qos: .background).async {
            let key = "ie2kiei2-\(sistema)"
            let key_p = key.leftPadding(toLength: 32, withPad: "0")
            
            var result = "erro"
            do {
                let aes = try AES(key: key_p, iv: "12493274392")
                let ciphertext = try aes.encrypt(Array(dados.utf8))
                let data = Data(bytes: ciphertext, count: ciphertext.count)
                result = data.base64EncodedString()
            } catch {
                print(error)
            }
            
            DispatchQueue.main.async {
                completion(result)
                // 任务完成后结束后台任务断言
                if backgroundTaskID != .invalid {
                    UIApplication.shared.endBackgroundTask(backgroundTaskID)
                    backgroundTaskID = .invalid
                }
            }
        }
    }
    
  3. 确保加密操作在低优先级后台线程执行
    把加密任务放到全局后台队列执行,避免占用主线程或高优先级线程,让系统更合理地调度后台资源。

额外注意事项

  • 后台任务断言的执行时间有限制(通常最多几分钟),如果加密的数据量极大,可能需要拆分任务或考虑其他方案。
  • 检查AES初始化代码:iv: "12493274392"的长度是否符合AES要求(比如AES-256需要16字节IV),长度不符合可能导致加密库内部异常,在后台环境下表现为停滞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 11:49:52