将代码更新为最新的 Swift 4 语法会导致“线程 1:致命错误:索引超出范围”错误

Posted

技术标签:

【中文标题】将代码更新为最新的 Swift 4 语法会导致“线程 1:致命错误:索引超出范围”错误【英文标题】:Updating code to latest Swift 4 syntax results in a "Thread 1: Fatal error: Index out of range" error 【发布时间】:2018-03-15 10:45:06 【问题描述】:

我目前正在将一些应用程序更新到最新的 Swift 4 语法并且遇到了问题,我确定我只是遗漏了一些非常明显的东西。

最初我的代码如下:

    let indices : [Int] = [0,1,2,3]
    //let newSequence = shuffle(indices)
    let newSequence = indices.shuffle()
    var i : Int = 0
    for(i = 0; i < newSequence.count; i++)
    
        let index = newSequence[i]
        if(index == 0)
        
            // we need to store the correct answer index
            currentCorrectAnswerIndex =  i

        

最初我对上面的代码有三个错误,即:

    Value of type '[Int]' has no member 'shuffle' C-style for statement has been removed in Swift 3 Unary operator '++' cannot be applied to an operand of type '@lvalue Int'

为了解决这些问题,我更改了代码,现在如下所示:

    let indices : [Int] = [0,1,2,3]
    //let newSequence = shuffle(indices)
    let newSequence = indices.shuffle()
    var i : Int = 0
    while i < newSequence.count i += 1

        let index = newSequence[i]
        if(index == 0)
        
            // we need to store the correct answer index
            currentCorrectAnswerIndex =  i

        

更改代码并在 Xcode 中运行 Product > Clean 后,我不再有任何错误。但是,当我在 ios 模拟器中使用该应用程序时,它会在某个时间点挂起,并且在 Xcode 中检查会在以下代码行中出现 Thread 1: Fatal error: Index out of range 错误:

let index = newSequence[I]

我已经阅读了有关 Swift 中相同错误的其他问题(请参阅:1、2、3 和 4),但这些似乎不适用于我的场景。

我知道我在这里遗漏了一些非常明显的东西,但目前它只是在逃避我。

有什么想法吗?

【问题讨论】:

有什么想法吗? – 是的:调试你的代码。如果newSequence[i] 给出索引超出范围错误,请在该行之前添加print(i)。然后你会很快看到你的错误是什么。 【参考方案1】:

Swift 3+ 等价的代码是

let indices : [Int] = [0,1,2,3]
let newSequence = indices.shuffle() // this seems to be a custom function

for i in 0..<newSequence.count

    let index = newSequence[i]
    if index == 0  // no parentheses in Swift
        // we need to store the correct answer index
        currentCorrectAnswerIndex = i
    


【讨论】:

【参考方案2】:

崩溃的原因是你增加i,对它执行一些操作,然后才检查它是否超出范围。要消除此错误,只需将 i += 1 移动到关闭的末尾即可。

但是为什么不使用快速枚举呢?您仍在尝试以旧方式执行循环,但使用新语法。而不是 C 方式

var i : Int = 0
while i < newSequence.count 
    let index = newSequence[i]
    if(index == 0)
    
        // we need to store the correct answer index
        currentCorrectAnswerIndex =  i

    

    i += 1

以正确的 Swift 方式进行操作

for (index, value) in newSequence.enumerated() 
    if value == 0 
        currentCorrectAnswerIndex =  index
    

【讨论】:

【参考方案3】:

更改(递增值)i 的位置,如下面的代码所示。 (i 的值在用于循环操作之前是递增的,因此在循环的最后/最后一次迭代期间,i 的值变得大于数组索引)

let indices : [Int] = [0,1,2,3]
//let newSequence = shuffle(indices)
let newSequence = indices.shuffle()
var i : Int = 0
while i < newSequence.count 

    let index = newSequence[i]
    if(index == 0)
    
        // we need to store the correct answer index
        currentCorrectAnswerIndex =  i

    
    i += 1 // Update (increment) value for i at last

更新

(正如 MartinR 所建议的)这会比你做的更好:

let indices : [Int] = [0,1,2,3]
let newSequence = indices.shuffle()

for (i, newSeqIndex) in newSequence.enumerated() 
    if (newSeqIndex == 0) 
        currentCorrectAnswerIndex =  i
    


【讨论】:

更好:for i in 0..&lt; newSequence.countfor i in newSequence.indices【参考方案4】:

您在其中放置了一个i += 1,而原始代码中没有。

【讨论】:

以上是关于将代码更新为最新的 Swift 4 语法会导致“线程 1:致命错误:索引超出范围”错误的主要内容,如果未能解决你的问题,请参考以下文章

将 XLPagerTabStrip 转换为 swift3 会导致错误

如何将以下代码从 Swift 2 转换为 Swift 5?

ios swift将文本字段设置为数字键盘时会导致奇怪的错误

将json调用语法从Objective-C转换为Swift的正确方法是啥?

将 FBO 保存到相机胶卷后清理后崩溃错误? Swift 2.0 选择器语法

Xcode 8/Swift 3:让 AP​​I 信息离线可用? [复制]