在Cocoa中使用/存储浮点数组

时间:2011-02-18 19:26:21

标签: iphone arrays cocoa cocoa-touch core-data

在c中,如果我想要一个浮点数组(例如),我只需定义固定大小并分配它,我就可以访问每个元素进行数学运算。但是,我希望能够让我的数组变得可变,因为它们的大小会不断增长(因为应用程序正在运行,并且数组可以轻松超过10000个元素)并且NSMutableArray的想法听起来很棒。但是,(如果我理解正确的话)它只存储对象,我必须将我的数字包装在NSNumber中,然后将它们放入数组中。这似乎只是存储浮点数组(或双精度数或整数数)的一大笔开销。

另一方面,我看到Core Data有flout属性,但是我没有看到如何以相同的方式访问它(array [index])。我在这里错过了什么吗?如果所有繁重的数学运算只能在固定大小的c数组中完成,是否有使用我没有偶然发现的基础类的方法,或者是否有方法可以访问核心数据对象,就像访问数组一样?

2 个答案:

答案 0 :(得分:1)

我会避免在NSNumbers中使用NSMutableArrays包装浮点数。正如你所说,这增加了一个荒谬的开销。

我建议使用C ++标准模板库(STL)容器。在您的情况下,vector将是最好的。

使用STL将意味着从Objective-C转移到Objective-C ++ ......并且需要将受影响源文件的扩展名从.m更改为.mm,并将#import添加到使用std的文件中: :矢量

另一种方法是使用NSMutableData对象 - 但是你可能最终会在附加数据(浮点数)时做更多的簿记。

答案 1 :(得分:1)

你在这里没有遗漏任何东西;对于c标量类型的数组,没有正式的objc接口。

简单的方法(如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 ...但你仍然修复了指针大小的值,所以你必须自己编写它。这不是特别难。缺点是你最终可能最终得到的变种数量。