NSArray 与 C 类型?

Posted

技术标签:

【中文标题】NSArray 与 C 类型?【英文标题】:NSArray with C types? 【发布时间】:2009-10-08 16:38:08 【问题描述】:

我想知道是否可以使用具有 C 类型作为元素的 NSArray/NSMuatbleArray,即 CGLayerRef?

如果将 CGLayerRef 对象添加到 NSMutableArray 代码会编译但会引发警告:

警告:传递参数 1 'objectForKey:' 使指针来自 没有强制转换的整数

因此我的问题是:如何将 C 类型存储在可变数组中?

最好的,

海因里希

【问题讨论】:

【参考方案1】:

这是一个多部分的答案。最后,你的答案将是“你可以做到”。

(1) NSArray 不能处理一般的 C 类型。如果你对这种东西感兴趣,CFArray 可以配备自定义回调来存储其他类型的数据。警告:通常您可以将 CFArray 传递给任何采用 API 的 NSArray - 它们是桥接的。这不适用于具有自定义回调的 CFArray。

(2) CGLayerRef 不是任何旧的 C 类型,它是一个 CFType。 CFType 被桥接到 NSObject。向任何 CFType 发送 -retain-release 就像在 NSObject 上一样。如果您要在实现-foo 的NSObject 上放置一个类别,然后将一些随机CFType 转换为id 并将-foo 消息发送给它,您会看到foo 的实现被调用。

所以,这里的编译器警告是唯一的问题。您可以强制转换为 (id) 以避免它。所有这些都受支持。

肯费里

可可框架

【讨论】:

【参考方案2】:

看看NSValue

NSValue 对象是单个 C 或 Objective-C 数据项的简单容器。它可以保存任何标量类型,例如 int、float 和 char,以及指针、结构和对象 ID。此类的目的是允许将此类数据类型的项目添加到集合中,例如 NSArray 和 NSSet 的实例,这要求它们的元素是对象。 NSValue 对象始终是不可变的。

【讨论】:

【参考方案3】:

NSMutableArray(或任何 NS 容器类型)只能存储 NSObject 子类的元素。不幸的是,这不包括典型的 C 指针类型,其中包括 CGLayerRef。

对此的一个警告是“免工具桥接”类,您可以将其从 C 指针类型转换为它们的 NS 等效项(例如,CFStringRef NSString*),但这些桥接显然是记录在案,而 CGLayerRef 似乎没有。

要注意的另一件事是,Objective-C 中的id 与指针不同,因此在这两种类型之间进行转换以尝试将 C 指针硬塞到 NS 容器中可能会给您带来麻烦。

正如另一个答案中提到的,您可以使用NSValue 包装您的C 指针并将NSValue 存储在您的NSMutableArray 中。

【讨论】:

以上是关于NSArray 与 C 类型?的主要内容,如果未能解决你的问题,请参考以下文章

NSArray与NSMutableArray的常用方法

OC数组的简单使用NSArray

NSArray 与 C Array 性能比较

Array 与 NSArray 的不同点对比表

Objective - C NSArray不可变数组和NSMutableArray可变数组

Objective C /iPhone:是不是可以重新初始化 NSArray?