gpt4 book ai didi

swift - 单元测试时 waitForExpectations 上的 EXC_BAD_ACCESS

转载 作者:可可西里 更新时间:2023-10-31 23:13:49 24 4
gpt4 key购买 nike

考虑以下简化结构:

class MyClass {
weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate: class {
func goneWrong()
}

以及抛出 EXC_BAD_ACCESS (0x40dedeadbec0) 错误的测试用例:

class MyTest: XCTestCase {
func test() {
let exp = expectation(description: "Expecting a call")
let a = MyClass()
a.delegate = MyMockDelegate(exp: exp)

// Thread 1: EXC_BAD_ACCESS(code=1, address=0x40dedeadbec0)
waitForExpectations(timeout: 10)
}

class MyMockDelegate: MyClassDelegate {
let exp: XCTestExpectation

init(exp: XCTestExpectation) {
self.exp = exp
}

func goneWrong() {
self.exp.fulfill()
}
}
}

如果委托(delegate) var 是正常声明的,没有 weak 关键字,则不会抛出错误。问题是它需要是弱的,以避免在真实代码(而不是测试用例)中的强引用循环。我该如何解决这个问题?

最佳答案

这是一个老问题,所以我相信你现在已经解决了,但为了 future 的读者,问题是你已经将你的委托(delegate)定义为 weak(即允许将其设置为 nil 并在对象不是强引用时立即释放对象)。但是您没有对 MyMockDelegate 实例的强引用:

let a = MyClass()
a.delegate = MyMockDelegate(exp: exp)

现在,我希望它在这种情况下优雅地nil delegate 引用,我不知道为什么在 0x40dedeadbec0 地址,因为我没有。 (顺便说一句,我不认为 0x40dedeadbec0 是一个真正的内存地址,而是一些内核开发人员的那些糟糕的双关语之一。)

无论如何,如果您希望您的模拟委托(delegate)能够工作,您需要保留对它的引用直到测试结束,例如:

class MyAppTests: XCTestCase {

func test() {
let exp = expectation(description: "Expecting a call")

var delegate: MyMockDelegate? = MyMockDelegate(exp: exp)

let a = MyClass()
a.delegate = delegate

// do something

waitForExpectations(timeout: 10)

delegate = nil
}
}

或者,您可以在测试类中创建一个属性,以在测试生命周期内保持对委托(delegate)的强引用。无论哪种方式,如果您不希望它消失在您身上,您需要不止一个 weak 引用。

关于swift - 单元测试时 waitForExpectations 上的 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40979634/

24 4 0
文章推荐: css - 如何在
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com