在c中,如果我想要一个浮点数组(例如),我只需定义固定大小并分配它,我就可以访问每个元素进行数学运算。但是,我希望能够让我的数组变得可变,因为它们的大小会不断增长(因为应用程序正在运行,并且数组可以轻松超过10000个元素)并且NSMutableArray的想法听起来很棒。但是,(如果我理解正确的话)它只存储对象,我必须将我的数字包装在NSNumber中,然后将它们放入数组中。这似乎只是存储浮点数组(或双精度数或整数数)的一大笔开销。
另一方面,我看到Core Data有flout属性,但是我没有看到如何以相同的方式访问它(array [index])。我在这里错过了什么吗?如果所有繁重的数学运算只能在固定大小的c数组中完成,是否有使用我没有偶然发现的基础类的方法,或者是否有方法可以访问核心数据对象,就像访问数组一样?
答案 0 :(得分:1)
我会避免在NSNumbers中使用NSMutableArrays包装浮点数。正如你所说,这增加了一个荒谬的开销。
我建议使用C ++标准模板库(STL)容器。在您的情况下,vector将是最好的。
使用STL将意味着从Objective-C转移到Objective-C ++ ......并且需要将受影响源文件的扩展名从.m更改为.mm,并将#import添加到使用std的文件中: :矢量
另一种方法是使用NSMutableData对象 - 但是你可能最终会在附加数据(浮点数)时做更多的簿记。
答案 1 :(得分:1)
简单的方法(如westsider所述)是使用std::vector
,然后使用CF / NS-Data等机制实现序列化/反序列化。
如果你愿意,你可以在一个objc接口中包装std :: vector:
/* MONDoubleArray.h */
/* by using pimpl, i'm assuming you are not building everything as objc++ */
struct t_MONDoubleArray_data;
@interface MONDoubleArray : NSObject < NSCoding, NSCopying, NSMutableCopying >
{
t_MONDoubleArray_data* data;
}
- (double)doubleAtIndex;
- (void)setDoubleAtiIndex:(double)index;
- (NSUInteger)count;
/*...*/
@end
/* MONDoubleArray.mm */
struct t_MONDoubleArray_data {
std::vector<double> array;
};
@implementation MONDoubleBuffer
- (id)init
{
self = [super init];
if (0 != self) {
/* remember your c++ error handling (e.g., handle exceptions here) */
array = new t_MONDoubleArray_data;
if (0 == array) {
[self release];
return 0;
}
}
return self;
}
/*...more variants...*/
- (void)dealloc
{
delete array;
[super dealloc];
}
- (NSData *)dataRepresentationOfDoubleData { /*...*/ }
- (void)setDoubleDataFromDataRepresentation:(NSData *)data { /*...*/ }
/*...*/
@end
然后,你已经完成了objc序列化而没有麻烦。
还有一种方法可以使用CF / NS_MutableArray作为标量,使用指针(或更窄)大小的条目:
@interface MONFloatBuffer : NSObject
{
NSMutableArray * floats;
}
@end
@implementation MONFloatBuffer
- (id)init
{
self = [super init];
if (0 != self) {
CFAllocatorRef allocator = 0; /* default */
CFIndex capacity = 0; /* resizable */
/* you could implement some of this, if you wanted */
const CFArrayCallBacks callBacks = { 0 /* version */ , 0 /* retain */ , 0 /* release */ , 0 /* copyDescription */ , 0 /* equal */ };
floats = (NSMutableArray*)CFArrayCreateMutable(allocator, capacity, &callBacks);
// now we can read/write pointer sized values to `floats`,
// and the values won't be passed to CFRetain/CFRelease.
}
return self;
}
@end
但是,如果没有自定义,它仍然无法正确反序列化。所以... NSPointerArray可以很容易地完成 more ...但你仍然修复了指针大小的值,所以你必须自己编写它。这不是特别难。缺点是你最终可能最终得到的变种数量。