【问题标题】:Objective-C classes in structs with ARC带有 ARC 的结构中的 Objective-C 类
【发布时间】:2012-06-01 14:11:12
【问题描述】:

我尝试制作一个包含类的结构,例如:

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

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

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

【问题讨论】:

  • 只是猜测,但根据我的经验,您需要包含unsafe_unretained,它可能只是默认为unsafe_unretained
  • @pcperini:然后它应该在自动释放池弹出后崩溃,但它没有。你的经验是 Objective-C 还是 Objective-C++?在 C 中它不能添加析构函数。
  • Objective-C :)

标签: objective-c struct automatic-ref-counting objective-c++


【解决方案1】:

4.3.5 of the ARC docs:

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

如果程序声明了 C 结构或联合的成员,则该程序是非良构的 拥有一个非平凡的所有权限定类型。

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

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

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

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

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

【讨论】:

  • 罗布说了什么!!我要补充一点,您还可以为非常薄的 ObjC++ 层关闭 ARC,手动管理内存,因为这样做将提供创建这种性质的可维护粘合层所需的精确和显式控制。
  • 所以最重要的是它是安全的,但它使结构不平凡?
  • 差不多;任何时候你在两种语言之间进行桥接——即使是在 Objective-C 和基于 C 的直接 CF 之间,尽管它更简单——由于边界处的阻抗不匹配,将会存在脆弱性和复杂性。这正是为什么希望保持边界尽可能小和完全隔离的原因;为每个 C++ 类或类似类创建一个简单的 Objective-C 包装器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多