【问题标题】:Code runs fine on Playground; at the same time it yields an EXC_I386_GPFLT error代码在 Playground 上运行良好;同时它产生一个 EXC_I386_GPFLT 错误
【发布时间】:2016-07-25 20:02:48
【问题描述】:

我遇到了一个奇怪的问题,其中 Playground 打印了预期的结果,但同时我看到一个错误,告诉我由于 EXC_I386_GPFLT 错误而停止执行。

我正在使用 Playground 来模拟应该如何使用我正在编写的 API 包装器。这样做的想法是为未来的开发人员规划一个不错的 API。

以下是我为规划包装器而编写的整个“规划”代码。随意将其复制并粘贴到 Playground 以查看实际问题:

class Anilist {
    init() {}

    internal class UserAPIs {
        weak var parent: Anilist? = nil

        init(parent: Anilist) {
            self.parent = parent
        }
    }

    lazy var user: UserAPIs = { [unowned self] in
        let userapi = UserAPIs(parent: self)
        return userapi
    }()
}

extension Anilist.UserAPIs {
    func me(_ completionHandler: (results: [String]) -> Void ) {
        // Do some logic, fetching stuff from parent
        completionHandler(results: ["Lorem", "Sammet"])
    }
}

let andy = Anilist()
andy.user.me { results in
    print(results)
}

奇怪的是,它正确地打印了["Lorem", "Sammet"],但同时我得到了那个错误。

我有read (for C++) 其他几个questions 关于此错误,但不幸的是我无法解决此问题。因为我可以收集到这是因为我试图访问零内存而发生的?一般来说,除了它是一种架构保护之外,我还没有找到更多关于此的信息。

虽然代码运行良好,但我还在犹豫是否要将它放在我的实际代码中,因为我不知道它会如何表现。即使它在第一次运行时有效,但从长远来看它是否会产生错误也很难预测。

编辑:

看起来它与计算出的lazy var 有关。将该行更改为:

lazy var user: UserAPIs = UserAPIs(parent: self)

按预期工作(如,它打印数组并且不会给我EXC_I386_GPFLT 错误)。

编辑 2:

以前的编辑似乎是不准确的信息。

【问题讨论】:

  • let _ = andy.user.me 解决了这个问题。并打印数组。
  • 哇哦,确实如此。嗯,这简直太迷人了……

标签: swift exc-bad-access swift-playground swift3


【解决方案1】:

这并不是真正的答案,而是一种解决方法,直到我弄清楚为什么会这样:

let andy = Anilist()
let someVar = andy.user.me { results in
    print(results)
}

这会给出一个编译时警告说constant someVar inferred to have type (), which maybe unexpected

但是这样做:

let andy = Anilist()
let _ = andy.user.me { results
    print(results)
}

工作正常,没有任何错误。够奇怪的。如果有人能解释为什么会发生这种情况,那就太好了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多