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

Xcode14.3/Swift5中数组索引越界崩溃异常排查求助

问题描述

我正在开发一款访问结构体数组的App,使用Xcode 14.3/Swift 5环境。循环执行时出现崩溃,报错信息为:

Thread 142: Fatal error: Index out of range

对应代码行:

if serverConfig.serverURL == self.appDelegate.serverConfigurations[index].serverURL 

但调试时获取到的信息显示:

(lldb) po self.appDelegate.serverConfigurations.count
5
(lldb) po index
2

按常理该索引不应触发越界崩溃,特此求助原因。

补充说明:serverConfigurations数组在AppDelegate的application(_:didFinishLaunchingWithOptions:)方法中构建,从UserDefaults读取字典数组并初始化ServerConfiguration实例,代码如下:

if let savedConfigurations = userDefaults.array(forKey: CONFIGURATION_KEY) {
        var index = 0;
        for item in savedConfigurations {
            let dictionaryConfig = item as! Dictionary<String, String>
            let serverConfig = ServerConfiguration.init(serverURL: String.init(dictionaryConfig[SERVER_URL_KEY]!) ,
                regionName:String.init(dictionaryConfig[REGION_NAME_KEY]!),
                isRefreshing: false,
                index: index,
                networkFailures: 0,
                lowFPSWarnings: 0)
            serverConfigurations.append(serverConfig)
            index += 1
            let serverStatus = ServerStatus.init(serverURL: dictionaryConfig[SERVER_URL_KEY],
                sim: nil,
                regionName: dictionaryConfig[REGION_NAME_KEY],
                fps: nil,
                timeDilation: nil,
                uniqueVisitors: nil,
                regionStatus: "Status: Unknown",
                restarts: nil,
                lastRestart: nil,
                lastUpdate: Date.distantFuture,
                statusUnknown: true,
                shownError: false)
            self.serverStatus.append(serverStatus)
    }
}
可能的原因与解决方法
  • 多线程竞态条件:崩溃发生在Thread 142,说明代码在非主线程执行。Swift的Array并非线程安全,若serverConfigurations同时被其他线程(比如主线程)执行删除、清空等修改操作,就会出现「调试时count为5,但访问瞬间数组长度已小于3」的矛盾情况。
    解决:给serverConfigurations的读写操作添加线程锁(比如NSLock),或改用线程安全容器;也可确保所有对该数组的访问都在同一线程(如主线程)执行。

  • 调试时机延迟:你在lldb中打印count和index时,崩溃已经发生,此时数组状态可能和崩溃瞬间不一致。比如崩溃时数组被修改为长度2,之后又被恢复为5,调试看到的是恢复后的状态。
    解决:在崩溃代码行前添加日志,实时打印serverConfigurations.count和index的值;或添加条件断点:当index >= serverConfigurations.count时触发,捕获崩溃瞬间的真实状态。

  • 数组被意外修改:检查代码其他位置是否存在对serverConfigurations的移除、重赋值操作,比如调用remove(at:)、removeAll(),或直接将数组赋值为空数组。这些操作可能在崩溃前瞬间执行。
    解决:给serverConfigurations添加属性观察者didSet,当数组变化时打印日志和调用栈,追踪修改来源。

  • 强制解包的潜在风险:代码中大量使用!强制解包(如dictionaryConfig[SERVER_URL_KEY]!),若UserDefaults数据格式有误,可能引发其他崩溃。虽当前崩溃指向索引越界,但仍建议替换为可选绑定,避免意外问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:10:32