我正在尝试为我正在处理的新应用程序设计数据结构,并且我正在使用核心数据(第一次)。
我一直在努力解决核心数据中缺少数组的问题,但我大部分时间都在解决这个问题。
我留下的一个问题是我的一个对象类型有一个“int”数组。我可能有很多这些整数,所以我希望它们具有空间效率。我也希望能够快速访问它们。
在我的特定情况下,我的int数组将只对它们执行两个操作。一种是迭代它们,第二种是添加新的int。最常见的操作(以及我需要保持最高效的操作)只是能够读取数组中的所有值。
对于存储,我认为我需要在我的对象上使用“二进制数据”属性。现在我想弄清楚将“int”打包成一个字节数组的最佳方法。
我的应用程序将创建目前仅在iOS设备上使用的数据,但未来可能会在其他计算机上使用,因此我想确保我的解决方案与架构无关,但同时也是最快的在具有较慢处理器且关注电池寿命的iOS设备上。
我正在考虑设计我的二进制数据,以便以“小端”格式存储整数。我的对象将是NSManagedObject的子类,它将有一个side字段(不是核心数据存储的一部分),它是一个“int *”指针,我将用它来迭代这些值。
当我的对象出现故障时,我会初始化c数组。如果endianness是“little endian”(我将使用CFByteOrderGetCurrent()确定),那么我可以使用以下代码非常有效地读取int数组:
@property (retain) NSData *data; // Core Data binary attribute
...
int *cArray = (int *) [self.data bytes];
如果字节序不是小端,我需要分配本地存储,正确解压缩int值,并使二进制属性和c-array保持最新状态。
我会在我的子类中添加代码来管理错误(例如,当出现故障时将cArray清零,并在出现故障时正确设置它。)
所以,我认为我有一个适合我的解决方案,虽然我不喜欢它。
如果有人能想出更好的方法来做我想做的事情,我会非常感激。
此外,如果有人能够想到为什么c-array和NSData之间的交互或核心数据可能会给我带来问题,我会非常感激。
谢谢, 罗恩
答案 0 :(得分:2)
在CoreData中执行此操作的典型方法是与对象建立一对多关系,该对象只有一个字段来保存int值。既然你说你将拥有很多这些int值,这很可能不会是一个令人满意的解决方案。
您还需要谨慎使用CoreData实体上的二进制类型,因为如果您的二进制数据足够大,这通常会导致一些与性能相关的不良问题。
如果这些选项都不可行,您可能需要考虑从CoreData下载到较低级别的存储机制,该机制使用更传统的数据库方法,并且能够在int值上有效地执行所有所需的功能。
答案 1 :(得分:1)
C标准允许有很多有趣的事情:
int
的奇数大小(过去常见的是16)我个人使用int32_t或(最好)uint32_t而不用担心奇怪的架构。我也不打扰CFByteOrderGetCurrent(),因为字节顺序在编译时是已知的:
#include <TargetConditionals.h>
#if TARGET_RT_LITTLE_ENDIAN
insert code here
#else
#error "Big endian architectures not supported yet!"
#endif
我也使用const int *
(因为NSData不可变)。
也可能无法保证self.data
在对象变成错误之前仍然有效 - 一般规则是“如果你想要一个对象存活,保留它”。也就是说,Core Data可能会持有这些对象。
最后,为什么需要将int指针存储在对象中?我只是按需生成它:
-(const int32_t*)intArray:(size_t*)count {
NSData * d = [[self.data copy] autorelease];
*count = [d length]/sizeof(int32_t);
return (const int32_t*)[d bytes];
}
复制/自动释放应该是有效的,但是用于确保即使在迭代期间设置self.data,迭代的数组也不会改变。