【问题标题】:Mutable array object types [duplicate]可变数组对象类型
【发布时间】:2013-04-22 21:38:32
【问题描述】:

我是第一次在 Objective C 上编程,来自 C++(到目前为止我喜欢 后者好多了!)。我有一个关于可变数组的问题,即我想创建一个具有我的对象之一的特定类型“CMParticle”,而不是通用 ID 类型。要从我的可变数组访问我的对象中的数据,我必须每次都将它转换为我的对象之一(我认为这很麻烦),如下所示:

rij[0] = ((CMParticle *)particles[*pi]).crds[0] - ((CMParticle *)particles[*pj]).crds[0];

其中“粒子”是我的可变 CMParticle 对象数组。我宁愿这样做

rij[0] = particles[*pi].crds[0] - particles[*pj].crds[0];

在此之前,我声明我的可变数组是这样的:

particles = [NSMutableArray array];

如果我能以某种方式用我的类型声明这个数组,那就太好了,这样我就不必每次都进行类型转换。有没有办法做到这一点?

【问题讨论】:

标签: objective-c


【解决方案1】:

您尝试做的事情在 Objective C 中实际上没有意义。

C++ 容器是同质的,但通用的。你可以有vector<CMParticle>vector<int>,它们是不同的类型。

ObjC 容器是异构的。你只有一个NSArray,它可以包含CMParticle 对象、NSNumber 对象或其他任何东西,所有这些都混合在一个大数组中。

您通常根本不需要这些演员表。如果您想向my_array[3] 发送消息,只需发送[my_array[3] doSomething:15]。就像高级语言(Python、Ruby、Smalltalk、Javascript 等)一样。

唯一的问题是(与 Python 等不同),在某些情况下您确实需要演员表。最关键(也是最烦人的),如果你想直接访问成员,你必须先施法。这是 ObjC(与 Python 等不同)鼓励您使用 @property 和/或显式访问器而不是直接访问成员的原因之一。 (另外,作为一个小麻烦,因为变量已经声明了类型,你不能只写tempval = my_array[3];,你必须指定类型,比如:CMParticle *tempval = my_array[3]。)

另一种看法:C++ 扩展了 C 的静态、弱类型系统,为您提供更强大的静态类型系统; ObjC 改为使用单独的 dynamic 类型系统(不幸的是,现有的 C 内容保持不变,这是偶尔出现问题的地方)。

您可以很容易地编写自己的NSMutableArray 子类,它是通用的(当然,与 C++ 的编译时不同,在运行时获取该类)和同质的,但所做的只是添加限制;元素仍将是id 无处不在。解决那个的唯一方法是为每个数组编写一个自定义类:MutableCMParticleArrayMutableNSNumberArray 等。

【讨论】:

  • 太好了,感谢您的帮助!
  • 什么?您不需要将数组元素的赋值类型转换为变量。这是索引访问器语法的问题吗?因为多年来我一直在用objectAtIndex: 编写等效代码,并且从来不需要转换。
  • @Chuck:对不起,我把那部分说得很有误导性。让我解决它。
  • objectAtIndex:objectAtIndexedSubscript: 都返回id,所以你不需要类型转换,声明会影响转换。 id 是最底层的类,为了进行类型检查,所有类型都是idid 响应所有消息。
  • @iluvcapra:答案已经说明了这一点。请参阅“您通常……”段落如果您想向my_array[3](或[my_array objectAtIndex:3])发送消息,只需向其发送消息即可。我不想解释这种工作背后的机制,因为它有点复杂(id 不是真正根类型——一方面,它是一个指针 i> 到根类型,另一方面,您通常可以将id 与不是根类型的子类的东西一起使用),我认为 OP 不需要了解那部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
相关资源
最近更新 更多