11

我尝试制作一个带有类的结构,例如:

struct my_struct
{
    NSString *string;
    // more fields
};

令我惊讶的是,Objective-C++ 在启用 ARC 的情况下允许这样做。
它将如何管理字符串?
它可以很容易地保留在每个作业中,但问题是释放。
它可以添加一个带有释放的析构函数,但这将使结构变得不平凡。
它也可以使它不保留或释放,但这样做应该有 unsafe_unretained。

根据我的观察,使用它时没有任何崩溃,但我想知道这里到底发生了什么。

4

1 回答 1

9

请参阅ARC 文档的 4.3.5

4.3.5。结构和联合的所有权限定字段

如果程序将 C 结构或联合的成员声明为具有非平凡的所有权限定类型,则该程序是格式错误的。

基本原理:在 C++ 意义上,生成的类型将是非 POD,但 C 并没有为我们提供非常好的语言工具来管理聚合的生命周期,因此简单地禁止它们更方便。仍然可以使用 void* 或 __unsafe_unretained 对象来管理它。

此限制不适用于 Objective-C++。但是,非平凡的所有权限定类型被认为是非 POD:在 C++11 术语中,它们不是平凡的默认可构造、可复制构造、可移动构造、可复制分配、可移动分配或可破坏的。使用 ARC 之外的类违反 C++ 的单一定义规则,在 ARC 下,该类将具有非平凡的所有权限定成员。

基本原理:与 C 不同,我们可以将所有权限定子对象的所有必要 ARC 语义表达为类的(默认)特殊成员函数的子操作。这些功能然后变得不平凡。这具有非显而易见的结果,即该类将具有非平凡的复制构造函数和非平凡的析构函数;如果这在 ARC 之外通常不成立,则该类型的对象将以与 ABI 不兼容的方式传递和返回。

如果您通读所有注意事项,我强烈建议您不要在 ObjC++ 中这样做。我强烈建议不要在任何情况下广泛使用 ObjC++。它是一种桥接语言,可以帮助纯 ObjC 和纯 C++ 相互交流。它有很多问题。将 ObjC++ 与 ARC 结合引入了 ObjC 中不会发生的时间和空间性能成本,以使其异常安全。定义这些特定于 ObjC++ 的数据结构使得与非 ObjC++ 代码和非 ARC 代码交互变得困难(请注意,您不能在 ARC 之外使用它)。您应该从 ARC 免费获得的大部分内容突然变得困难,因为您不得不再次担心内存管理(正如您已经发现的那样)。

构建一个纯 ObjC 层。构建一个纯 C++ 层。构建一个薄的 ObjC++ 层将两者联系在一起。不要将 ObjC 对象放在结构中,绝对不要放在任何公共结构中(即在定义它的单个 ObjC++ 对象之外可见)。

于 2012-06-01T14:28:29.527 回答