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

iOS Swift 5.1下UIPickerView数组越界致命错误的解决方法

解决UIPickerView的“Index out of range”错误

咱们先来定位问题的根源:你遇到的数组越界错误,核心是在numberOfRowsInComponent方法中直接访问pShipmentCategories[selected]时,pShipmentCategories的长度可能小于等于selected的值,或者对应索引的元素根本不存在。

为什么会出现这个情况?

从你的调试信息和接口数据来看,大概率是异步请求的时序问题:

  • 你已经成功获取到计划日期数据,pPlandateCategories有值,但运单数据是依赖计划日期的异步请求,当UIPickerView第一次加载时,pShipmentCategories可能还没被填充数据,甚至连和pPlandateCategories匹配的空数组结构都没有。
  • 比如pPlandateCategories有2个元素,但pShipmentCategories是空数组,这时候selected=0访问pShipmentCategories[0]自然会触发越界错误。

具体修复方案

1. 先对齐pShipmentCategories的结构

当你拿到计划日期数据后,先初始化pShipmentCategories为对应数量的空数组,确保它的长度和pPlandateCategories完全匹配:

// 解析计划日期接口返回后执行
pPlandateCategories = ["20190826", "20190827"]
// 初始化对应数量的空数组,避免后续索引访问失败
pShipmentCategories = Array(repeating: [String](), count: pPlandateCategories.count)

2. 在所有数组访问前加安全判断

修改PickerView的几个核心方法,添加索引有效性检查,彻底避免越界:

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if component == 0 {
        return pPlandateCategories.count
    } else {
        let selected = pickerView.selectedRow(inComponent: 0)
        // 先判断selected是否在有效索引范围内
        guard selected < pShipmentCategories.count else {
            return 0
        }
        return pShipmentCategories[selected].count
    }
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if component == 0 {
        guard row < pPlandateCategories.count else {
            return nil
        }
        return pPlandateCategories[row]
    } else {
        let selected = pickerView.selectedRow(inComponent: 0)
        // 双重安全校验:先校验日期索引,再校验运单行索引
        guard selected < pShipmentCategories.count, row < pShipmentCategories[selected].count else {
            return nil
        }
        return pShipmentCategories[selected][row]
    }
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if component == 0 {
        pickerView.reloadComponent(1)
    } else {
        let selected = pickerView.selectedRow(inComponent: 0)
        guard selected < pShipmentCategories.count, row < pShipmentCategories[selected].count else {
            someTextField.text = "Shipment: N/A"
            return
        }
        someTextField.text = "Shipment:" + " " + pShipmentCategories[selected][row]
    }
}

3. 运单数据加载完成后刷新PickerView

当你获取到某一天的运单数据后,更新pShipmentCategories对应位置的数组,再刷新第二个组件:

// 解析20190827的运单数据后执行
if let dateIndex = pPlandateCategories.firstIndex(of: "20190827") {
    pShipmentCategories[dateIndex] = ["4505023244", "4505023274"]
    yourPickerView.reloadComponent(1)
}

这样就能从根源上避免数组越界的问题啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:15:00