Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 斯威夫特:用试一试?捕捉超出范围的索引_Ios_Swift - Fatal编程技术网

Ios 斯威夫特:用试一试?捕捉超出范围的索引

Ios 斯威夫特:用试一试?捕捉超出范围的索引,ios,swift,Ios,Swift,所以我在做游戏,有一个网格,你只能在任何相邻的块是源块的情况下放置,如果你试图在顶部网格中放置一个块,上面没有块,那么索引超出范围的错误将被抛出。我试图捕捉它,但xcode似乎认为不可能出现错误。我做错了吗?我想我可以去每一个案件,并添加一个捕获,但我觉得这应该工作 如果您想在自己的IDE中试用,请复制友好文本: func isValidPlacement(row:Int,col:Int) -> Bool { if let t = try? tiles[row-1][co

所以我在做游戏,有一个网格,你只能在任何相邻的块是源块的情况下放置,如果你试图在顶部网格中放置一个块,上面没有块,那么索引超出范围的错误将被抛出。我试图捕捉它,但xcode似乎认为不可能出现错误。我做错了吗?我想我可以去每一个案件,并添加一个捕获,但我觉得这应该工作

如果您想在自己的IDE中试用,请复制友好文本:

func isValidPlacement(row:Int,col:Int) -> Bool {
        if let t = try? tiles[row-1][col], t.isSource {
            return true
        }
        else if let t = try? tiles[row][col-1], t.isSource {
            return true
        }
        else if let t = try? tiles[row+1][col], t.isSource {
            return true
        }
        else if let t = try? tiles[row][col+1], t.isSource {
            return true
        }
        else {
            return false
        }
    }

访问不存在的数组的索引会导致运行时异常。您不能使用try here,因为数组没有抛出任何内容

尝试在func的开头添加这两行,然后去掉所有Try

guard row <= tiles.count - 1 else {
    return false
}
guard col <= tiles[row].count - 1 else {
    return false
}

Swift中的
防护栏。您只能捕获由代码引发的
错误
实例,无法捕获运行时异常,例如数组边界冲突

您可以创建自己的
safeAccess
功能。您没有说明数组中的类型,因此我将使用
SomeType
作为示例

func safeAccess(row:Int, col:Int) -> SomeType? {
   guard row >= 0, row < tiles.count else {
       return nil
   }

   guard col >= 0, col < tiles[row].count else {
       return nil
   }

   return tiles[row][col]
}

func isValidPlacement(row:Int,col:Int) -> Bool {

    if let t = tiles.safeAccess(row:row-1,col:col), t.isSource {
        return true
    }

    if let t = tiles.safeAccess(row:row,col:col-1),, t.isSource {
        return true
    }

    if let t = tiles.safeAccess(row:row+1,col:col), t.isSource {
        return true
    }

    if let t = tiles.safeAccess(row:row,col:col+1), t.isSource {
        return true
    }

    return false

}
使用它:

func isValidPlacement(row:Int,col:Int) -> Bool {
    if let tiles = tiles.element(at:row-1), let t = tiles.element(at:col), t.isSource {
        return true
    }
    else if tiles.element(at:row), let t = tiles.element(at:col-1), t.isSource {
        return true
    }
    else if let tiles = tiles.element(at:row+1), let t = tiles.element(at:col), t.isSource {
        return true
    }
    else if let tiles = tiles.element(at:row), let t = tiles.element(at:col+1), t.isSource {
        return true
    }
    else {
        return false
    }
}

运行时错误和返回布尔值是Objective-C的方法!扔,扔!请仔细阅读警告。它明确指出,需要一个
throw
ing函数来捕获错误。但是,不会引发超出范围的异常。如果
为0,或者它们是最后一行/列,该怎么办?仍应检查有效位置。为什么要进行否决投票?如果我的答案有问题,请告诉我是什么。谢谢你解决了我的问题。我不知道你不能像其他语言一样捕捉IndexOutOfBounds。你甚至连我的问题都被否决了(他们在这里冷酷无情,哈哈。我也投了反对票。这个答案太混乱和限制性了。我的目的不是整理OP的代码,而是解释他们为什么会出错以及如何处理这种情况。这是StackOverflow,不是CodeReview。)
extension Array {
    func element(at index: Int) -> Element? {
        if index >= 0 && index < self.count {
             return self[index]
        }
        return nil
    }
}
func isValidPlacement(row:Int,col:Int) -> Bool {
    if let tiles = tiles.element(at:row-1), let t = tiles.element(at:col), t.isSource {
        return true
    }
    else if tiles.element(at:row), let t = tiles.element(at:col-1), t.isSource {
        return true
    }
    else if let tiles = tiles.element(at:row+1), let t = tiles.element(at:col), t.isSource {
        return true
    }
    else if let tiles = tiles.element(at:row), let t = tiles.element(at:col+1), t.isSource {
        return true
    }
    else {
        return false
    }
}