扩展CLPlacemark时EXC_BAD_ACCESS-在定义范围之外访问变量

Ted*_*urt 2 unit-testing memory-management ios swift

我有一个问题,我已经找到解决方法,但是我想了解为什么它不起作用-因为这对我来说毫无意义。这是一个演示我的问题的最小示例:

import XCTest
import CoreLocation

class ExampleTests: XCTestCase {

    var okay: ext!

    // this test works fine
    func testOkay(){
        okay = ext()
        XCTAssertNotNil(okay)
    }

    // this test crashes with EXC_BAD_ACCESS(code=1, address=0x10)
    func testNotOkay(){
        let notOkay: ext
        notOkay = ext()
        XCTAssertNotNil(notOkay)
    }
}

extension ExampleTests {
    class ext : CLPlacemark{

    }
}
Run Code Online (Sandbox Code Playgroud)

我正在看一本书,以开发一个简单的TodoList应用程序,该应用程序使用CoreLocation对地址进行地理编码。作为测试的一部分,我必须创建一个模拟CLPlacemark对象以测试地理编码功能。

在这本书中,我被告知我必须为此模拟程序声明一个变量作为Test类的属性,因为否则“由于在其定义范围之外访问了地标,因此测试会崩溃”。

可以在上面的示例中看到。testOkay()正常工作,因为它okay被声明为类属性。由于出现错误而testNotOkay()崩溃EXC_BAD_ACCESS,因为我尝试实例化ext该函数中的新实例。

现在,如果我不扩展CLPlacemark,问题就解决了-即我可以ext在函数中声明类型类型的变量,或者在类的属性中声明类型,而没有问题。

这里发生了什么?我看不出为什么第二个示例在第一个示例工作时会崩溃。在我的实际代码中,仅在一个或两个函数中使用我的模拟地标实例作为类属性时,将它们声明为类属性似乎很轻而易举。肯定有一些我不了解Swift的问题导致了这个问题。

谢谢!!

Kam*_*ski 5

我最近在测试功能时遇到此问题,该功能需要提供预定义的CLPlacemark实例作为输入。经过研究,我发现有人在CLBeacon课堂上也有类似的问题。

将CLBeacon设置为nil时为EXC_BAD_ACCESS

地标对象通常由CLGeocoder对象生成,尽管您也可以自己显式创建它们。

尽管Apple文档说您可以CLPlacemark自己创建实例。当涉及子类化时,此类并不是一个好人。这取决于所谓的私有类CLPlacemarkInternalnil当你创建一个实例。在下图中,您可以看到此对象在调试器中的外观。所述_internal的ivar具有价值的0x0nil

屏幕截图

EXC_BAD_ACCESS当您实例化的对象被释放时,发生消息崩溃。无论您超出范围还是将另一个对象(或nil)分配给变量。为什么会这样呢?这是苹果开发人员的问题。但是下面您可以找到其他人实施的一些解决方法。