Swift调用函数时出现Thread 1数组下标越界错误排查
解决Swift数组下标越界(Index out of range)问题
你遇到的Thread 1: Fatal error: Index out of range错误,根源在于代码里先访问数组元素,再检查下标合法性,导致当下标超出数组范围时直接触发崩溃。咱们一步步拆解问题,再给出修复方案。
问题分析
先看你的checkAlerts函数逻辑:
- 循环一开始就直接访问
alertNotificationArray[alertNotificationArrayPosition],但此时并没有检查这个下标是否在0...alertNotificationArray.count-1的合法范围内 - 你的条件分支是在访问元素之后才处理下标递增/重置,这就导致如果
alertNotificationArrayPosition刚好等于alertNotificationArray.count(也就是超出了最后一个元素的下标),在执行访问代码时直接触发越界错误
比如,当alertNotificationArrayPosition走到数组的count值时,数组的最大合法下标是count-1,这时候访问alertNotificationArray[alertNotificationArrayPosition]必然崩溃,而你的下标重置逻辑是在访问之后才执行的,根本没机会触发。
修复方案
第一步:添加安全下标扩展(可选但推荐)
先给Array加一个安全下标,避免直接访问越界下标时崩溃:
extension Array { subscript(safe index: Int) -> Element? { // 先判断下标是否在数组的合法索引范围内 return indices.contains(index) ? self[index] : nil } }
第二步:重构checkAlerts函数逻辑
调整代码顺序,先检查下标合法性,再访问元素,同时优化循环条件和下标处理逻辑:
func checkAlerts() { // 把循环条件改成更安全的范围判断,避免下标越界后无限循环 while trackingCoordinatesArrayPosition < trackingCoordinatesArray.count - 1 { // 先确保tracking数组的下标合法 guard let trackingCoordinate = trackingCoordinatesArray[safe: trackingCoordinatesArrayPosition] else { trackingCoordinatesArrayPosition += 1 continue } // 确保alert数组的下标合法,不合法就重置下标并移动tracking指针 guard let alertCoordinate = alertNotificationArray[safe: alertNotificationArrayPosition] else { alertNotificationArrayPosition = 0 trackingCoordinatesArrayPosition += 1 continue } let trackingLatitude = trackingCoordinate.latitude let trackingLongitude = trackingCoordinate.longitude let alertLatitude = alertCoordinate.latitude let alertLongitude = alertCoordinate.longitude if trackingLatitude == alertLatitude && trackingLongitude == alertLongitude { print("found problem") // 匹配成功后,同时移动两个下标,避免重复检查同一元素 alertNotificationArrayPosition += 1 trackingCoordinatesArrayPosition += 1 } else { // 没匹配上时,先尝试移动alert下标,到末尾再重置并移动tracking下标 if alertNotificationArrayPosition < alertNotificationArray.count - 1 { alertNotificationArrayPosition += 1 } else { trackingCoordinatesArrayPosition += 1 alertNotificationArrayPosition = 0 } } } }
关键修改点说明:
- 先检查再访问:用
guard let结合安全下标,确保只有下标合法时才访问元素,避免崩溃 - 优化循环条件:把
!=改成<,避免下标超出范围后进入无限循环 - 调整下标处理逻辑:在没匹配上时,先判断alert下标是否还有剩余元素,再决定是移动alert下标还是重置并移动tracking下标
- 匹配成功后的处理:同时移动两个下标,避免重复检查同一个元素,提升效率
额外提醒
另外,比较经纬度时直接用==可能会有精度问题,因为CLLocationCoordinate2D的latitude和longitude是Double类型,浮点运算有精度误差,建议用abs(trackingLatitude - alertLatitude) < 1e-6这样的方式判断是否近似相等,避免因为微小精度差导致匹配失败。
内容的提问来源于stack exchange,提问作者Vincenzo
相关产品推荐
相关产品推荐

