开发者

Using/storing an array of floats in Cocoa

In c, if I wanted an array of floats (for instance) I would just define the fixed size and allocate it, and I could access each element for math operations. However, I want the ability to have my arrays be mutable since they will continually grow in size (as the app is running, and the array could easily surpass 10000+ elements) and the idea of NSM开发者_Go百科utableArray sounds great. However, (if I understand correctly) it only stores objects, I would have to wrap my numbers in NSNumber, and then put those into the array. That seems like a ridiculous amount of overhead to just store an array of floats (or doubles or integers).

On the other hand, I see that there are flout attributes for Core Data, but I don't see how I could access this in the same way ( array[index] ). Am I missing something here? Should all heavy-lifting math just be done in fixed-sized c arrays, are there ways of using the foundation classes that I haven't stumbled upon, or are there ways of accessing core data objects like one would access an array?


you aren't missing anything here; there's not a formal objc interface for arrays of c scalar types.

the simple way (as westsider mentioned) is to use std::vector, and then implement serialization/deserialization using a mechanism such as CF/NS-Data.

you could wrap std::vector in an objc interface, if you wanted:

/* 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

then, you'd have accomplished objc serialization without hassle.

there's also a way to use a CF/NS_MutableArray for scalars, using pointer (or narrower) sized entries:

@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

however, that would still fail to properly deserialize itself without customization. so... NSPointerArray would accomplish that more easily... but you still fixed to pointer sized values, so you have to write it yourself. which not terribly hard. the downside is the number of variants you may ultimately end up with.


I would avoid wrapping your floats in NSNumbers and using NSMutableArrays. As you say, this adds a ridiculous amount of overhead.

I would recommend using C++ Standard Template Library (STL) containers. In your case, vector would be the best.

Using STL will mean moving from Objective-C to Objective-C++ ... and it will require changing extensions of effected source files from .m to .mm, as well as adding #import to files that make use of std::vector.

Another approach would be to use an NSMutableData object - but you would probably end up doing more of the bookkeeping wrt appending data (floats).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜