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

求和响应数组值时抛出异常,应用崩溃问题求助

嘿,我来帮你排查这个问题!这种情况十有八九是代理传递的数组存在未初始化/类型不匹配/为空的问题——毕竟手动测试正常,说明你的求和逻辑本身是没问题的。

先看最可能的崩溃场景(附错误代码示例)

假设你的代理相关代码是这样的:

// 代理协议定义
protocol DataPassingDelegate: AnyObject {
    func didReceiveData(_ data: [Int]?)
}

// 前一个ViewController传递数据
class PreviousVC: UIViewController {
    weak var delegate: DataPassingDelegate?
    
    func sendData() {
        // 这里可能因为异步请求未完成、数据解析失败,传了nil
        let data: [Int]? = nil 
        delegate?.didReceiveData(data)
    }
}

// 当前ViewController接收数据并求和
class CurrentVC: UIViewController, DataPassingDelegate {
    var receivedArray: [Int] = []
    
    func didReceiveData(_ data: [Int]?) {
        // 直接强制解包nil数组,必崩!
        receivedArray = data! 
        sumArrayMethod1(receivedArray)
    }
    
    // 求和方法1:遍历累加
    func sumArrayMethod1(_ array: [Int]) -> Int {
        var sum = 0
        for num in array {
            sum += num
        }
        return sum
    }
    
    // 求和方法2:reduce简化
    func sumArrayMethod2(_ array: [Int]) -> Int {
        return array.reduce(0, +)
    }
}

崩溃的核心原因

  1. 强制解包可选值:代理传递的数组可能是nil(比如异步请求没返回、数据解析出错),你用data!强制解包直接触发崩溃——手动测试时你传的是确定的非空数组,所以不会暴露这个问题。
  2. 元素类型不匹配:如果代理传递的是[Any]类型数组(比如OC转Swift的场景),里面混了String或其他非数字类型,求和时会因为类型转换失败崩溃。
  3. 回调时机过早:代理在数组还没被正确初始化时就回调了(比如网络请求还没完成就调用了didReceiveData),导致拿到空数组之外的无效数据。

针对性解决办法

办法1:安全处理可选数组,杜绝强制解包

修改回调逻辑,先做非空校验再赋值:

func didReceiveData(_ data: [Int]?) {
    // 先判断数组是否有效,无效则给默认空数组并提示
    guard let validData = data, !validData.isEmpty else {
        print("代理传递的数组为空或未初始化")
        receivedArray = []
        return
    }
    receivedArray = validData
    // 现在调用求和方法绝对安全
    let sum1 = sumArrayMethod1(receivedArray)
    let sum2 = sumArrayMethod2(receivedArray)
    print("求和结果:方法1=\(sum1),方法2=\(sum2)")
}

办法2:处理元素类型不匹配的情况

如果代理传递的是[Any]类型数组,先过滤出合法的数字元素:

// 修改代理协议(如果原协议是传递[Any]的话)
protocol DataPassingDelegate: AnyObject {
    func didReceiveData(_ data: [Any]?)
}

// 在回调中做类型校验
func didReceiveData(_ data: [Any]?) {
    guard let rawData = data else {
        receivedArray = []
        return
    }
    // 只保留Int类型的元素,自动过滤无效类型
    let validData = rawData.compactMap { $0 as? Int }
    if validData.count != rawData.count {
        print("数组中存在非数字元素,已自动过滤")
    }
    receivedArray = validData
    let sum = receivedArray.reduce(0, +)
    print("安全求和结果:\(sum)")
}

办法3:确保代理回调时机正确

在数据完全准备好后再触发代理回调(比如网络请求完成后):

// 前一个ViewController中,异步请求完成后再回调
func fetchDataFromNetwork() {
    // 模拟网络请求
    DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
        let fetchedData = [1,2,3,4,5] // 确保是已解析完成的有效数组
        DispatchQueue.main.async {
            self.delegate?.didReceiveData(fetchedData)
        }
    }
}

总结

核心原则就是不要盲目信任代理传递的参数,手动测试时你能控制数据的有效性,但代理传递的可能因为异步逻辑、数据错误等出现异常,必须提前做安全校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:25:26