2013-04-06 32 views
5

Tôi đang cố gắng lưu trữ c-float array trong một NSDictionary để sử dụng sau này.
Ban đầu tôi đã sử dụng một số NSArray để lưu trữ C-data nhưng NSArray là để làm chậm ý định của mình.Lưu trữ một mảng float C trong một NSDictionary

Tôi đang sử dụng đoạn mã sau để bọc các mảng trong NSDictionary:

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

Và lấy mảng C-phao sử dụng:

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

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

[posValues getValue:&posMorphs]; 

Khi tôi retireve mảng , các giá trị đều được đặt thành 0.0 cho mỗi chỉ mục sai.

Làm cách nào để khắc phục sự cố này?

Trả lời

2

NSValue có thể có ý nghĩa cho giá trị vô hướng, không phải mảng cho chúng. Trong trường hợp này, sử dụng NSData nên dễ dàng hơn nhiều

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

giải pháp khác là phân bổ mảng trên heap và sử dụng NSValue để lưu trữ các con trỏ.

+0

Nó hoạt động với mảng (xem câu trả lời dưới đây). Nhưng 'NSData' có thể là giải pháp tốt hơn. –

+0

Đã hoạt động hoàn hảo. Cảm ơn bạn rất nhiều – samb90

0

Tôi không chắc liệu đó có phải là cách bạn mã hóa giá trị của bạn hay không, nhưng nó có thể giúp đóng gói mảng của bạn thành một cấu trúc.

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

Trong mã của bạn:

// 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]); 

Lợi ích đối với phương pháp này là mảng của bạn được giữ như một loại mảng. Ngoài ra, các cấu trúc này có thể được gán cho dù các mảng thô không phải là:

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

p2 = p1; 
1

Bạn có thể nạp byte vào NSDictionary nếu chúng được bao bọc trong NSData.

Nếu bạn muốn bỏ qua điều đó, bạn sẽ sử dụng NSMapTableNSPointerFunctionsOpaqueMemory (hoặc MallocMemory) cho các hàm con trỏ giá trị.

3

Tôi cũng nghĩ rằng NSData có lẽ là giải pháp tốt nhất ở đây. Nhưng chỉ nếu có ai quan tâm: Bạn không thể sử dụng @encode với một mảng có kích thước có thể thay đổi, vì nó là chỉ thị biên dịch . Do đó

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

không thể hoạt động. Trên thực tế trình biên dịch tạo mã hóa cho một mảng float có kích thước bằng không ở đây, điều này giải thích tại sao bạn không nhận được gì khi đọc NSValue.

Nhưng bạn có thể tạo chuỗi mã hóa kiểu khi chạy.Đối với một mảng float, mã hóa là [<count>^f] (xem Type Encodings), vì vậy sau đây sẽ làm việc:

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

+1 Điểm tốt về chỉ thị của trình biên dịch. Rất vui khi tìm hiểu điều gì đó mới mẻ. Tuy nhiên, tôi tự hỏi tại sao nó không đưa ra bất kỳ cảnh báo nào. – Sulthan

+0

@Sulthan: Đó là một câu hỏi hay! –

Các vấn đề liên quan