【问题标题】:What happens when you pass a NSMutable* object to a method accepting a NS* object?当您将 NSMutable* 对象传递给接受 NS* 对象的方法时会发生什么?
【发布时间】:2023-03-26 02:21:02
【问题描述】:

我刚开始使用 Objective-C,我有一个关于功能的问题。 假设我有一个接受和存储NSDictionary 对象的方法,并且我为它提供了NSMutableDictionary(毕竟是NSDictionary)。此方法将其存储在对象中,在NSDictionary 属性中,因此对象的类型实际上变为NSDictionary。这意味着用于将对象添加到 NSMutableDictionary 的选择器不再存在。

我来自 C++ 背景,虽然我应该尽量不将 Objective-C 实践映射到 C++ 实践,但这看起来与 C++ 中处理 constness 的方式非常相似(即,如果您通过非const 到接受相同类型的 const 变体的方法,对象在方法(以及实例)范围内变为 const

有人能告诉我吗?

谢谢,
托马索

【问题讨论】:

  • 总质子反转。
  • (不要从 C++ 的角度思考const,将 NSMutableX 视为 NSX 的子类。您可以将 NSMutableX 传递给需要 NSX 的方法,但反之则不行,并且没有玩演员表等会改变这一点。)
  • (实际上,NSX 和 NSMutableX 是“类集群”的成员,不在严格的类层次结构中,但内部标志强制区分可变/不可变,无论您如何转换或操纵指针。)

标签: c++ objective-c constants parameter-passing immutability


【解决方案1】:

这部分问题:

此方法将其存储在对象中,在NSDictionary 属性中,因此对象的类型实际上变为NSDictionary

... 是假的。不发生类型转换。该对象仍然是一个NSMutableDictionary,只是不再从接口明确说明它是这样的。

Objective-C 对象在运行时是无类型的。键入是为了您作为程序员的利益,并允许编译器生成适当的警告。强制转换指针与在 C++ 中强制转换指针的效果完全相同——它对所指向的东西没有任何影响。在这种情况下,您所做的只是将指向可变事物的指针转换为指向不可变事物的指针(就编译器而言,这是一个超类,因此允许强制转换为隐式)。

如果您想获取可变对象的不可变副本,请使用copycopy 总是返回一个不可变的副本,即使原始副本是可变的,mutableCopy 也是可变副本所必需的。使用 copy 修饰符声明属性,以便为您完成前者。不必担心对已经不可变的对象进行不必要的复制——它们会将自己作为副本返回(执行适当的内存所有权簿记)。

【讨论】:

  • 是否可以通过翻转一点来使可变对象不可变,而无需实际复制整个对象?
  • 不,不是,至少通过官方 API。这样的事情将是一个设计缺陷。如果对象 A 和 B 都拥有可变数组 N 的所有权,则 B 将 N 翻转为不可变,则 A 处于无效状态。
猜你喜欢
  • 1970-01-01
  • 2015-08-15
  • 2017-06-20
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多