2013-04-06 3 views
5

Я пытаюсь сохранить c-float array в NSDictionary, чтобы использовать его позже.
Первоначально я использовал NSArray для хранения C-данных, но NSArray должен замедлять мои намерения.Хранение массива C float в NSDictionary

Я использую следующий код, чтобы обернуть массивы в NSDictionary:

[self.m_morphPositions setObject:[NSValue valueWithBytes:&positionBuff objCType:@encode(float[(self.m_countVertices * 3)])] forKey:fourCC]; 

И извлекая массив C-Float с помощью:

float posMorphs[(self.m_countVertices*3)]; 

NSValue *posValues = [self.m_morphPositions objectForKey:name]; 

[posValues getValue:&posMorphs]; 

Когда я retireve массив , для всех индексов все значения равны 0.0, что неверно.

Как это исправить?

ответ

2

NSValue, вероятно, предназначен для скалярных значений, а не для массивов. В этом случае использование NSData должно быть намного проще

NSData* data = [NSData dataWithBytes:&positionBuff length:(self.m_countVertices * 3 * sizeof(float))];
[data getBytes:posMorphs length:(self.m_countVertices * 3 * sizeof(float))];

Другим решением является выделение массива в куче и использовать NSValue для хранения указателя.

+0

Он работает с массивами (см ответа ниже). Но 'NSData' может быть лучшим решением. –

+0

Работал отлично. Большое спасибо – samb90

0

Я не уверен, что это то, как вы кодируете свою ценность, но это может помочь инкапсулировать ваш массив в структуру.

// Put this typedef in a header 
typedef struct 
{ 
    float values[3]; 
} PosValues; 

В коде:

// store to NSValue 
PosValues p1 = { { 1.0, 2.0, 3.0 } }; 
NSValue *val = [NSValue valueWithBytes:&p1 objCType:@encode(PosValues)]; 

// retrieve from NSValue 
PosValues p2; 
[val getValue:&p2]; 

NSLog(@"%f, %f, %f", p2.values[0], p2.values[1]. p2.values[2]); 

Преимущество такого подхода состоит в том, что ваш массив хранится как тип массива. Кроме того, эти структуры являются назначаемыми, даже если исходные массивы не являются:

PosValues p1 = { { 1.0, 2.0, 3.0 } }; 
PosValues p2; 

p2 = p1; 
1

Вы можете кормить байты в NSDictionary, если они обернуты в NSData.

Если вы хотите пропустить это, вы должны использовать NSMapTable и NSPointerFunctionsOpaqueMemory (или MallocMemory) для функций указателя значений.

3

Я также считаю, что NSData, вероятно, является лучшим решением здесь. Но только если кому-то интересно: вы не можете использовать @encode с массивом с переменным размером, потому что это директива компилятора . Поэтому

@encode(float[(self.m_countVertices * 3)]) 

не может работать. На самом деле компилятор создает кодировку для массива float размером 0 здесь, что объясняет, почему вы ничего не получаете при чтении NSValue.

Но вы можете создать строку кодировки типа во время выполнения.Для массива поплавка, кодирования [<count>^f] (см Type Encodings), так что следующий будет работать:

const char *enc = [[NSString stringWithFormat:@"[%d^f]", (self.m_countVertices * 3)] UTF8String]; 
NSValue *val = [NSValue valueWithBytes:positionBuff objCType:enc]; 
+0

+1 Хороший вопрос о директиве компилятора. Приятно узнать что-то новое. Однако, интересно, почему он не выдает никаких предупреждений. – Sulthan

+0

@ Султан: Это хороший вопрос! –

Смежные вопросы