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

Swift中查看自动录制音频文件时触发数组越界错误的原因排查

问题原因与解决方案

崩溃原因

你遇到的运行时错误是字符串索引越界,根源在于自动定时生成的录音文件名长度不足26位,执行let start = fileName.index(fileName.startIndex, offsetBy: 26)时,因字符串总长度不够无法完成偏移,导致崩溃。

手动录制的文件名符合你预设的格式(长度至少满足26位前缀 + 4位.wav后缀),但自动录音生成的文件名格式或长度发生了变化,才触发了这个问题。

解决步骤

1. 统一手动/自动录音的文件名格式

先检查自动录音功能的文件名生成代码,确保和手动录制的格式完全一致。比如手动生成的文件名可能是Recording_202405201234567890123456.wav(固定前缀+长时间戳),自动生成的可能前缀缩短、时间戳位数减少,导致总长度不足。

2. 给索引操作加安全校验

即使文件名格式统一,也应该给字符串索引操作加安全判断,避免因意外情况(比如文件名被修改)再次崩溃。修改addToRecordings函数中的对应代码:

for file in wavFiles{
    let fileName = file.lastPathComponent
    // 确保文件名长度足够:需要至少26位(start偏移) + 4位后缀 = 30位
    guard fileName.count >= 30 else {
        print("跳过格式异常的文件:\(fileName)")
        continue
    }
    let start = fileName.index(fileName.startIndex, offsetBy: 26)
    let end = fileName.index(fileName.endIndex, offsetBy: -4)
    let range = start..<end
    let id = Int(fileName[range]) ?? 0
    // 后续代码保持不变...
}

3. 改用更可靠的ID提取方式

依赖固定偏移量提取ID的方式很脆弱,建议换用更灵活的方式:

  • 如果文件名格式是前缀_数字.wav,可以用字符串分割提取:
let fileName = file.lastPathComponent
let nameWithoutExt = fileName.replacingOccurrences(of: ".wav", with: "")
let parts = nameWithoutExt.components(separatedBy: "_")
let id = parts.last.flatMap(Int.init) ?? 0
  • 或者用正则表达式匹配文件名中的数字部分:
import Foundation

let fileName = file.lastPathComponent
let regex = try! NSRegularExpression(pattern: "\\d+")
let nsRange = NSRange(fileName.startIndex..., in: fileName)
let id = regex.firstMatch(in: fileName, range: nsRange)
    .flatMap { Range($0.range, in: fileName) }
    .map { String(fileName[$0]) }
    .flatMap(Int.init) ?? 0

总结

先统一手动和自动录音的文件名生成规则,再通过安全校验或更灵活的ID提取方式替换固定偏移量的写法,就能彻底解决这个崩溃问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:05:33