Xcode 如何成功访问程序无法访问的数据?

How can Xcode successfully access data the program cannot?

我是 运行宁 Xcode 9,Swift 4,High Sierra。在我的代码中,我有一个映射,它被剪切和剥离,将其作为闭包的第一行包括在内:

let foo = graph.edges.map { (edge: Edge<Node>) -> (Int, Int) in
    print(edge)
    let fromvertex = (edge.from as? VertexElement)
        .
        .
        .
}

let from vertex ...

行有断点

当运行时,代码成功到断点,这就是问题开始的地方。如果那时我在调试器中执行 po edge.from,我会得到预期的结果。如果我一步一步执行赋值,我得到 Thread 1: EXC_BAD_ACCESS (code=2, address=*whatever*)。然后我可以在那个时候执行 po edge.from 甚至 po (edge.from as? VertexElement) 并且仍然得到预期的结果。

怎么会这样? edge.from 中没有涉及可选项,而且我认为数据正确存在,因为调试器找到了它。

Edge 是(如您所料)通用的 class,定义的第一部分是这样的:

public class Edge<T>: NSObject, NSCoding, Codable where T: Hashable {
    public typealias Weight = SimWeight

    public let from: Vertex<T>
    public let to: Vertex<T>
    public var weight: Weight? = nil
        .
        .
        .
}

然后,Vertex 的第一部分,也是一个通用的,如下所示:

public struct Vertex<T>: Equatable, Codable where T: Hashable {
    public var data: T
    public let index: Int
    public var gridX: Int?
    public var gridY: Int?
        .
        .
        .
}

节点是另一个具体的 class(不是通用的)

最后,我打开了地址清理功能。

综上所述,我既看不出异常是从哪里来的,也看不出为什么调试器可以在程序无法获取数据的情况下获取数据。任何想法出了什么问题(或者甚至如何调试它?)

我只能怀疑是编译器问题,因为现在通过重新组织代码修复了它。具体来说,我在 Edge 中创建了这个方法:

func indirectEdge() throws -> IndirectEdge {
    guard let fromvx = self.from as? VertexElement,
        let tovx = self.to as? VertexElement,
        let weight = self.weight else {throw TypeError.notVertex}
    return IndirectEdge(from: fromvx.index, to: tovx.index, weight: weight)
}

然后将 post 顶部的代码更改为:

guard let indirectEdges = try? graph.edges.map({ (edge) throws -> IndirectEdge in
    return try edge.indirectEdge()
}) else {throw SimFileError.unimplementedOperation(why: "Don't know how to encode this graph")}
    .
    .
    .

那时一切都开始正常工作,没有例外。 (是的,我更改了后面的代码以接受 IndirectEdge;该代码在后面,应该不会有任何影响。)我 预期 的是异常将移至 indirectEdge 方法,但事实并非如此。很好,代码现在可以运行了,但可怕的是我不知道为什么。