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

时间:2016-12-17 18:48:17

标签: ios swift unit-testing memory-management

我有一个问题,我已经弄清楚如何修复,但我想了解它为什么不起作用 - 因为它对我没有意义。这是一个演示我的问题的最小例子:

testOkay()

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

在书中,我被告知我已经将此模拟的变量声明为Test类的属性,否则"测试会因为地点标记被访问而崩溃其定义范围。"

这可以在上面的例子中看到。 okay工作正常,因为testNotOkay()被声明为类属性。 EXC_BAD_ACCESSext错误而崩溃,因为我已尝试在函数中实例化ext的新实例。

现在,如果我不扩展CLPlacemark ,问题就会消失 - 即我可以在函数中声明类型close()的变量,或者作为类的属性声明没有问题

这里发生了什么?我认为没有理由为什么第二个例子在第一个例子工作时会崩溃。在我的实际代码中,当我们的模拟地标实例仅在一个或两个函数中使用时,将它们声明为类属性似乎是无聊的。必须有一些我不了解Swift导致这个问题的事情。

谢谢!

2 个答案:

答案 0 :(得分:4)

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

EXC_BAD_ACCESS when setting a CLBeacon to nil

  

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

尽管Apple文档说您可以自己创建CLPlacemark个实例。在进行子类化时,这个类不是一个好人。它取决于一个名为CLPlacemarkInternal的私有类,它在创建实例时为nil。在下图中,您可以看到此对象在调试器中的外观。 _internal ivar的值0x0nil

screenshot

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

答案 1 :(得分:0)

我也遇到了完全相同的问题。 我改用子类MKPlacemark。 最终,这使我能够设置所需的模拟属性,以完成测试