iOS应用程序在退出时崩溃

时间:2012-08-13 00:28:25

标签: objective-c memory-management exc-bad-access destructor objective-c++

我遇到了一个问题,我的iOS应用程序在退出时崩溃了,我将其缩小到这个范围:

// File.h

struct Name {
    NSString *name;
}

// File.mm

Name names[] = {
    @"foo",
    @"bar",
};

当应用程序退出时(按下iPad上的主页按钮),objc_msgSend的{​​{1}}崩溃了。它正在发生在析构函数EXC_BAD_ACCESS (SIGSEGV)

Name::~Name()

请记住,这是在.mm文件中,所以它被编译为obj-c ++。

这已经好几个月了。我不确切知道它何时开始发生,但我怀疑是在我更新到xcode 4.4时。

0 libobjc.A.dylib 0x37586e3a objc_release + 10 1 MyApp 0x0014abfc Name::~Name() (NameManager.h:21) 2 MyApp 0x0014ab42 Name::~Name() (NameManager.h:21) 3 MyApp 0x0014ad94 __cxx_global_array_dtor + 120 4 libsystem_c.dylib 0x36bba1cc __cxa_finalize + 216 5 libsystem_c.dylib 0x36b854f6 exit + 6 文字应该受到多个版本的保护(或者一直都是),但我认为无论如何都不会发生这种情况。

有人知道xcode 4.4中有什么变化吗?

我可以通过执行以下操作来修复崩溃:

NSString

但是我讨厌这样做而不理解为什么之前有效的东西不再起作用。或许它永远不应该有效。我也担心内存覆盖过多,所以这可能只是一种症状。

在DEBUG和RELEASE中都会发生这种情况。

更新:我在~Name()中放了一个断点,并验证内存没有损坏。 LLDB能够转储NSString OK。但是当我走的时候它会崩溃。

1 个答案:

答案 0 :(得分:1)

当您在Objective-C ++中声明包含启用了ARC的Objective-C对象的“普通旧数据”struct时,编译器有义务提供一个析构函数,该析构函数正确释放结构的ObjC成员,即使你自己不写。

  

此限制不适用于Objective-C ++。然而,非常重要   所有权限定类型被认为是非POD:在C ++ 11术语中,它们   不是简单的默认可构造,复制可构造,移动   可构造的,可复制的,可移动的可分配的或可破坏的。它   是违反C ++的一个定义规则来使用外面的类   在ARC下,ARC将具有非常重要的所有权限制   构件。

当您声明Name结构时,编译器会为您编写一个涉及隐式强保持Objective-C对象的析构函数。在执行时,这意味着C ++析构函数会删除它所期望的C ++结构,而是将指针串起来。如果没有有效的指针,-release ARC会在尝试取消引用不存在的接收器时尝试发送段错误。

当你声明一个Objective-C成员__unsafe_unretained时,它告诉ARC将它从它必须编写的析构函数中排除,因此结构只是被销毁,而-release永远不会被发送。建议您将结构或类中的所有Objective-C对象标记为__unsafe_unretained,并自行提供适当的内存管理,因为ARC可以使跨语言的对象生命周期复杂化。

相关问题