【问题标题】:Objective-C Containers that take objects接受对象的 Objective-C 容器
【发布时间】:2013-05-22 14:06:52
【问题描述】:

我正在通过翻译一些我为 Android 游戏编写的 Java 代码来完成我在 Objective-c 中的第一步(在很久很久之后)。似乎没有容器可以接收对象,而不先将其转换为id?或者有吗?

具体来说,这是我正在尝试使用的代码:

NSMutableArray *touchedBodies = [[NSMutableArray alloc] init];
// some additional code
if(![touchedBodies containsObject:(id)body]) {
    [touchedBodies addObject:(id)body];
}

containsObject 行通过正常,但在touchedBodies addObject:(id)b 上我收到“错误访问”错误。我要添加的主体是合法的 Box2D b2Body

当我尝试直接添加主体而不强制转换时:

[touchedBodies addObject:body];

编译器报错“无法使用 b2Body* 类型的左值初始化 id 类型的参数”

我错过了什么?

【问题讨论】:

  • 应该可以的。在上面写着// some additional code 的地方你还有什么?

标签: objective-c nsmutablearray


【解决方案1】:

首先,您永远不需要转换为 id 类型,因为您可以将 id 视为 Java 中的 Object 类:它是一种不需要显式的隐式向上转换。

在第二种情况下出现问题是因为2dBody 是 C++ 类,而不是 Objective-C 类。虽然您可以混合使用 Objective-C++ 和 C++ 代码(前者是后者的超集),但如果没有一些变通方法,您不能混合使用这两种语言的对象。

你主要有三个解决方案:

  • 如果2dBody 是一个指针,则将其包装在NSValue:[touchedBodies addObject:[NSValue valueWithPointer:body]] 中,这会引入一些对象分配开销,并且您需要在使用它时进行强制转换,2dBody *b = (2dBody*)[value pointerValue]
  • 如果2dBody 不是指针,那么您可以使用NSData:[NSData dataWithBytes:.. length:..],这会引入开销,内存管理问题(除非您使用noCopy 变体),如果类不是标准的,无论如何你都需要强制转换它
  • 忘记可可集合并使用 STL 集合,它们的性能更高,并且可以无缝管理所有内容:vector<2dBody> touchedBodies; touchedBodies.push_back(body);

我强烈建议使用 STL 集合,我个人使用这种方法

【讨论】:

  • 注意:NSData 复制仅在对象是标准布局类型时才有效。是的 - std::vector<2dBody> 绝对是在这种情况下使用 +1 的类型。
  • 非常感谢,@Jack。但是当我尝试它时, std::vector touchBods;我收到编译器错误“b2Body 未引用值”。这是什么意思?
  • 另一个错误是“命名空间'std'中没有名为'vector'的成员”
  • 我尝试更改编译器,如下所示stackoverflow.com/questions/12819886/…,但没有成功。
  • 你发的那个链接肯定能解决问题,你的Xcode是哪个版本的?你#include <vector>?如果启用了 C++11,我不确定您是否需要 using namespace std;,您可以直接使用 vector 而不是 std::vector 来引用它。
猜你喜欢
  • 1970-01-01
  • 2017-12-10
  • 1970-01-01
  • 2014-03-22
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多