【问题标题】:Array empty when it should clearly contain elements数组应该清楚地包含元素时为空
【发布时间】:2016-12-27 11:11:50
【问题描述】:

我不断收到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包含相似的元素,不能为空

【问题讨论】:

  • 您应该在显示错误之前删除所有不相关的代码,最好将示例代码粘贴到 Playground 中并运行。这会让其他人更容易看到发生了什么。

标签: ios swift xcode swift2 fatal-error


【解决方案1】:

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

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

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

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

也许:

func randomElement(fromArray array:[T]) -> T? {
        让 upperBound = UInt32(array.count)
        guard upperBound > 0 else { return nil }
        让 index = Int(arc4random_uniform(upperBound))
        返回数组[索引]
    }

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

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

【讨论】:

  • 是的,刚刚检查过:arc4random_uniform(0) 确实返回零。我猜是 arc4random 的一种边缘情况。
  • 显然,同样的问题将适用于所有其他数组查找。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 1970-01-01
  • 2013-02-19
  • 2019-08-05
  • 1970-01-01
  • 2017-09-20
相关资源
最近更新 更多