Использование / хранение массива с плавающей точкой в ​​Какао - PullRequest
3 голосов
/ 18 февраля 2011

В c, если бы я хотел массив с плавающей точкой (например), я бы просто определил фиксированный размер и выделил его, и я мог бы получить доступ к каждому элементу для математических операций. Тем не менее, я хочу, чтобы мои массивы были изменяемыми, поскольку они будут постоянно увеличиваться в размере (поскольку приложение работает, а массив может легко превысить 10000+ элементов), и идея NSMutableArray звучит великолепно. Однако (если я правильно понимаю) он хранит только объекты, мне нужно будет обернуть мои числа в NSNumber, а затем поместить их в массив. Это просто смешное количество накладных расходов на хранение массива чисел с плавающей точкой (или двойных или целых).

С другой стороны, я вижу, что для Базовых Данных есть атрибуты flout, но я не вижу, как я мог бы получить к ним такой же доступ (массив [индекс]). Я что-то здесь упускаю? Должна ли вся тяжелая математика быть выполнена в массивах c фиксированного размера, есть ли способы использования базовых классов, на которые я не наткнулся, или есть способы доступа к основным объектам данных, как если бы вы обращались к массиву?

Ответы [ 2 ]

1 голос
/ 19 февраля 2011

вы ничего здесь не упускаете; не существует формального интерфейса objc для массивов скалярных типов C.

простой способ (как упоминал westsider) - использовать std::vector, а затем реализовать сериализацию / десериализацию с использованием такого механизма, как CF / NS-Data.

вы можете обернуть std :: vector в интерфейс objc, если хотите:

/* 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 ... но вы по-прежнему будете использовать значения указателя, поэтому вы должны написать их самостоятельно. что не очень сложно. недостатком является количество вариантов, с которыми вы можете в конечном итоге столкнуться.

1 голос
/ 18 февраля 2011

Я бы не стал переносить ваши поплавки в NSNumbers и использовать NSMutableArrays. Как вы говорите, это добавляет смешные накладные расходы.

Я бы порекомендовал использовать контейнеры C ++ Standard Template Library (STL). В вашем случае, вектор будет лучшим.

Использование STL будет означать переход от Objective-C к Objective-C ++ ... и для этого потребуется изменить расширения используемых исходных файлов с .m на .mm, а также добавить #import в файлы, использующие std: :. вектор

Другим подходом может быть использование объекта NSMutableData - но вы, вероятно, в конечном итоге сделаете больше бухгалтерии с добавлением данных (с плавающей точкой).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...