ios - 数组在本应明确包含元素时为空

标签 ios swift xcode swift2 fatal-error

我不断收到 fatal error: Index out of range 错误。我的数组应该清楚地包含下图中的元素,但它是空的。几个小时以来一直在尝试调试它,我不太确定是什么原因造成的。请参阅下面的图片和代码。

        var topTest = [t2, t4, t8, t7, t2, t5, t8, t6 ]
    for (index, point) in topTest.enumerate() {

        spritesPath.append(point)

        if index < topTest.count - 1    {

        var previousArrayIndex = (index - 1)%topTest.count
        if previousArrayIndex == -1 {
            previousArrayIndex += topTest.count
        }
        var nextArrayIndex = (index + 1)%topTest.count

        var firstIndex = topPositions.indexOf(point)
        var secondIndex = topPositions.indexOf(topTest[nextArrayIndex])
        var firstArray = top[firstIndex!]
        var secondArray = top[secondIndex!]
        var middleIndex1 = 0
        var middleArray1 = [CGPoint]()
        var middleRandomArrayLength1 : UInt32 = 0
        var middleRandomPointIndex1 = 0
        var middleIndex2 = 0
        var middleArray2 = [CGPoint]()
        var middleRandomArrayLength2 : UInt32 = 0
        var middleRandomPointIndex2 = 0

        if point.x > topTest[nextArrayIndex].x {

            if point.x > topTest[previousArrayIndex].x   {

                let rightPositionsX = rightPositions.map({ $0.x })
                middleArray1 = firstArray.filter({rightPositionsX.contains($0.x)})

                middleRandomArrayLength1 =  UInt32(middleArray1.count)
                middleRandomPointIndex1 = Int(arc4random_uniform(middleRandomArrayLength1))
                spritesPath.append(middleArray1[middleRandomPointIndex1])

                middleIndex1 = rightPositions.indexOf(middleArray1[middleRandomPointIndex1])!
                middleArray1 = right[middleIndex1]
                let middleArray1X = middleArray1.map({ $0.x })
                var midArray2 = secondArray.filter({middleArray1X.contains($0.x)})
                midArray2 = midArray2.filter({element in point.x > element.x && topTest[nextArrayIndex].x < element.x })

                middleRandomArrayLength2 =  UInt32(midArray2.count)
                middleRandomPointIndex2 = Int(arc4random_uniform(middleRandomArrayLength2))
                spritesPath.append(middleArray2[middleRandomPointIndex2])
            }
            else{
                let secondArrayX = secondArray.map({ $0.x })
                middleArray1 = firstArray.filter({secondArrayX.contains($0.x)})

                middleArray1 = middleArray1.filter({element in point.x > element.x && topTest[nextArrayIndex].x < element.x })
                middleRandomArrayLength1 =  UInt32(middleArray1.count)
                middleRandomPointIndex1 = Int(arc4random_uniform(middleRandomArrayLength1))
                spritesPath.append(middleArray1[middleRandomPointIndex1])

            }
        }

else
        {

            if point.x < topTest[previousArrayIndex].x   {
                let leftPositionsX = leftPositions.map({ $0.x })
                middleArray1 = firstArray.filter({leftPositionsX.contains($0.x)})
                middleRandomArrayLength1 =  UInt32(middleArray1.count)
                middleRandomPointIndex1 = Int(arc4random_uniform(middleRandomArrayLength1))
                spritesPath.append(middleArray1[middleRandomPointIndex1])

                middleIndex1 = leftPositions.indexOf(middleArray1[middleRandomPointIndex1])!
                middleArray1 = left[middleIndex1]
                let middleArray1X = middleArray1.map({ $0.x })
                var midArray2 = secondArray.filter({middleArray1X.contains($0.x)})

                midArray2 = midArray2.filter({element in point.x < element.x && topTest[nextArrayIndex].x > element.x })

                middleRandomArrayLength2 =  UInt32(midArray2.count)
                middleRandomPointIndex2 = Int(arc4random_uniform(middleRandomArrayLength2))
                spritesPath.append(midArray2[middleRandomPointIndex2])
            }

            else    {
                let secondArrayX = secondArray.map({ $0.x })
                middleArray1 = firstArray.filter({secondArrayX.contains($0.x)})
                middleArray1 = middleArray1.filter({element in point.x < element.x && topTest[nextArrayIndex].x > element.x })
                middleRandomArrayLength1 =  UInt32(middleArray1.count)
                middleRandomPointIndex1 = Int(arc4random_uniform(middleRandomArrayLength1))
                spritesPath.append(middleArray1[middleRandomPointIndex1])
             }
        }
    }
    }

下图显示 secondArraymiddleArray 包含类似的元素,不应为空

enter image description here

enter image description here

enter image description here

最佳答案

我想我可以看到一个问题。崩溃的行是:

spritesPath.append(middleArray2[middleRandomPointIndex2]) 对吧?

所以我的理论是,如果 middleArray2 为空,则 arc4random_uniform 返回的索引为零。但是该数组没有第 0 个元素。

如果是这样,请在获取数组元素之前检查此条件。可能是将随机索引代码分解到它自己的函数中的好时机,您经常使用它并且它会简化您的设计。

也许:

func randomElement(fromArray array:[T]) -> T? {
        let upperBound = UInt32(array.count)
        guard upperBound > 0 else { return nil }
        let index = Int(arc4random_uniform(upperBound))
        return array[index]
    }

    let a = randomElement(fromArray: [1, 2, 3, 4, 5, 6, 7])    // 4
    let b = randomElement(fromArray: ["red", "green", "blue"]) // "red"
    let c = randomElement(fromArray: [Double]())               // nil

这个函数返回一个可选的,因为数组可能没有任何要返回的元素!

关于ios - 数组在本应明确包含元素时为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39053471/

相关文章:

ios - 带按钮的选择器 View 转到下一页

swift - ios8/swift : Buttons inside UICollectionView Cell?

ios - 如何为 Mapbox 注释创建自定义标注?

ios - 在 XCode 上归档多个目标并一次性构建多个 IPA 文件(需要脚本或命令)

ios - 为什么 Date Picker 背景颜色变化在运行时不可见?

ios - 使用 swift 的 DestinationViewController Segue 和 UINavigationController

ios - 如何同时翻转和旋转标签?

ios - 托管对象值随机为空(包括示例项目)

ios - Swift - UIViews 以编程方式排序

swift - 稍后在 Xcode 中生成 .strings 文件