广度优先搜索:线程 1:Swift 运行时失败:强制解包一个 nil 值
Breadth First Search: Thread 1: Swift runtime failure: force unwrapped a nil value
我尝试编写一个“圆点”游戏。因此,我必须对 UIButtons 的二维数组进行 Breath First Search 以找到从 playerButton 到边框的最短路径。
不幸的是,我有时会在几天内收到 线程 1:Swift 运行时故障:强制解包一个零值 错误我就是找不到问题所在。
这是程序的一个功能,return要移动下一个x和y坐标。那就是我做 BFS 的地方。
func findDirection()->String{
var blocked: [String] = []
let queue = otherQueue<Pair>()
let pair = Pair()
var possibleNeighbours = findPossibleNeighbours(btn: btnArr[playerX][playerY], blockedArr: blocked)
for neighbour in possibleNeighbours{
if(isOnBorder(point: neighbour)){
return neighbour
}
pair.setPair(firstValue: neighbour, secondValue: neighbour)
queue.enqueue(key: pair)
blocked.append(neighbour)
}
//Start the search
while(!queue.isEmpty){
let pointPair = queue.dequeue()
// !!!!!! THIS IS THE ERROR LINE:
let button = btnArr[getXFromString(string: (pointPair?.getFirst())!)][getYFromString(string: (pointPair?.getFirst())!)]
possibleNeighbours = findPossibleNeighbours(btn: button, blockedArr: blocked)
for neighbour in possibleNeighbours{
if isOnBorder(point: neighbour){
return (pointPair?.getSecond())!
}
pair.setPair(firstValue: neighbour, secondValue: (pointPair?.getSecond())!)
queue.enqueue(key: pair)
blocked.append(neighbour)
}
}
return "-1 -1"
}
问题:
它说 pointPair?.getFirst()!
被强制展开一个 nil 值。 pointPair 是我从队列中取出的 Pair。所以我的猜测是我的队列是空的并试图出列。查了好几遍,竟然写了一个新的QueueClass。那不是问题, !queue.isEmpty
工作正常,这是 while-condition。下一个猜测是 getFirst(),return 是我的 Pair 的第一个值,return 是一个 nil 值。这对我来说也没有意义,因为第一个值是 possibleNeighbours-Array 的迭代 neighbour
,它不能为 nil(如果它是可能的邻居并且显然存在,它只会添加到数组中)。
当点只有两种可能的移动方式时,问题总是会发生。以这个为例
蓝点从 (4, 4) 开始。然后我点击 (2, 3),点移动到 (3, 3)。然后我点击 (2, 4),点移动到 (3, 4)。然后按钮必须有可能的方式:移动到 (2, 5) 或 (3, 5)。如果您现在单击两者之一,它会崩溃。在控制台中,我可以读到在单击 (2, 5) 后队列仅包含 ["3 5"] 这是正确的,因为 (3, 5) 是继续前进的唯一方法。不知何故,它不会移动到那里,并用力崩溃并解开一个 nil 值...
如果你想下载我的整个项目并测试它,你可以这样做 here(希望 link 有效)。
您知道失败的原因吗? :(
感谢您的帮助!
您的问题在于 otherQueue
中的 dequeue
函数如何工作。您在返回数据之前调整指针,这导致在从具有一个条目的队列中移除头部后返回 nil
。
尝试类似...
func dequeue() -> T? {
if self.head?.data == nil { return nil }
let result = head?.data
if let nextItem = self.head?.next {
head = nextItem
} else {
head = nil
}
return result
}
此外,您不应该在 while(!otheryQueue.isEmpty || otheryQueue.dequeue() != nil)
中调用 dequeue
。
我尝试编写一个“圆点”游戏。因此,我必须对 UIButtons 的二维数组进行 Breath First Search 以找到从 playerButton 到边框的最短路径。
不幸的是,我有时会在几天内收到 线程 1:Swift 运行时故障:强制解包一个零值 错误我就是找不到问题所在。
这是程序的一个功能,return要移动下一个x和y坐标。那就是我做 BFS 的地方。
func findDirection()->String{
var blocked: [String] = []
let queue = otherQueue<Pair>()
let pair = Pair()
var possibleNeighbours = findPossibleNeighbours(btn: btnArr[playerX][playerY], blockedArr: blocked)
for neighbour in possibleNeighbours{
if(isOnBorder(point: neighbour)){
return neighbour
}
pair.setPair(firstValue: neighbour, secondValue: neighbour)
queue.enqueue(key: pair)
blocked.append(neighbour)
}
//Start the search
while(!queue.isEmpty){
let pointPair = queue.dequeue()
// !!!!!! THIS IS THE ERROR LINE:
let button = btnArr[getXFromString(string: (pointPair?.getFirst())!)][getYFromString(string: (pointPair?.getFirst())!)]
possibleNeighbours = findPossibleNeighbours(btn: button, blockedArr: blocked)
for neighbour in possibleNeighbours{
if isOnBorder(point: neighbour){
return (pointPair?.getSecond())!
}
pair.setPair(firstValue: neighbour, secondValue: (pointPair?.getSecond())!)
queue.enqueue(key: pair)
blocked.append(neighbour)
}
}
return "-1 -1"
}
问题:
它说 pointPair?.getFirst()!
被强制展开一个 nil 值。 pointPair 是我从队列中取出的 Pair。所以我的猜测是我的队列是空的并试图出列。查了好几遍,竟然写了一个新的QueueClass。那不是问题, !queue.isEmpty
工作正常,这是 while-condition。下一个猜测是 getFirst(),return 是我的 Pair 的第一个值,return 是一个 nil 值。这对我来说也没有意义,因为第一个值是 possibleNeighbours-Array 的迭代 neighbour
,它不能为 nil(如果它是可能的邻居并且显然存在,它只会添加到数组中)。
当点只有两种可能的移动方式时,问题总是会发生。以这个
蓝点从 (4, 4) 开始。然后我点击 (2, 3),点移动到 (3, 3)。然后我点击 (2, 4),点移动到 (3, 4)。然后按钮必须有可能的方式:移动到 (2, 5) 或 (3, 5)。如果您现在单击两者之一,它会崩溃。在控制台中,我可以读到在单击 (2, 5) 后队列仅包含 ["3 5"] 这是正确的,因为 (3, 5) 是继续前进的唯一方法。不知何故,它不会移动到那里,并用力崩溃并解开一个 nil 值...
如果你想下载我的整个项目并测试它,你可以这样做 here(希望 link 有效)。
您知道失败的原因吗? :(
感谢您的帮助!
您的问题在于 otherQueue
中的 dequeue
函数如何工作。您在返回数据之前调整指针,这导致在从具有一个条目的队列中移除头部后返回 nil
。
尝试类似...
func dequeue() -> T? {
if self.head?.data == nil { return nil }
let result = head?.data
if let nextItem = self.head?.next {
head = nextItem
} else {
head = nil
}
return result
}
此外,您不应该在 while(!otheryQueue.isEmpty || otheryQueue.dequeue() != nil)
中调用 dequeue
。