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
相关产品推荐
相关产品推荐

