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

UIPickerView索引越界致命错误:双选择器数据量不一致致崩溃

问题分析与解决方案

嘿,我一眼就找到触发「Index out of range」错误的原因了!咱们来拆解问题:

核心错误点

在pickerView(_:numberOfRowsInComponent:)方法中,你错误地给techniker选择器返回了materialien.count作为行数,而不是它对应的数据源email.count:

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    var countrows : Int
    if pickerView == artikel {
        countrows = materialien.count
    } else {
        countrows = materialien.count // 这里错了!应该是email.count
    }
    return countrows
}

当email和materialien的元素数量不一致时,比如你的例子里email有5个元素,materialien有6个,techniker选择器会被设置成显示6行,但email数组只有5个元素。当用户滑动到第6行时,代码尝试访问email[row](此时row=5),就会直接触发数组越界的致命错误。

修正后的完整代码

我不仅修复了这个错误,还优化了代码结构,让逻辑更清晰:

import UIKit
import MessageUI

class ViewController: UIViewController, MFMailComposeViewControllerDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
    @IBOutlet weak var techniker: UIPickerView!
    @IBOutlet weak var artikel: UIPickerView!
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var label1: UILabel!
    
    var email = ["email1@email.ch", "email2@email.ch", "email3@email.ch", "email4@email.ch", "email5@email.ch"]
    var materialien = ["article", "article", "article", "article", "article", "article"]
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        // 用switch判断更清晰
        switch pickerView {
        case artikel:
            return materialien.count
        case techniker:
            return email.count
        default:
            return 0
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch pickerView {
        case techniker:
            return email[row]
        case artikel:
            return materialien[row]
        default:
            return nil
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        switch pickerView {
        case techniker:
            label.text = email[row]
        case artikel:
            label1.text = materialien[row]
        default:
            break
        }
    }
}

额外优化建议

  • 使用switch代替多个if判断,代码可读性更强,也不容易漏写分支
  • 给默认分支返回0或nil,避免出现未处理的选择器情况
  • 可以考虑给每个选择器单独设置数据源和代理,进一步分离逻辑(如果后续功能更复杂的话)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:20:24