2010-10-18 113 views
5

回到我每天愚蠢的問題。今天我試圖把一個結構放在一個NSArray中。好吧,這很簡單,將它包裝在NSData中。如果你認識我,你就知道你即將看到代碼。在這個例子中,我將Wavefront OBJ中的一條頂點線加載到一個結構中並將其粘貼到一個數組中。將結構存儲在NSArray中

 NSArray *verticeLineParts = [currentLine componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 
     Coordinate c = CoordinateMake([[verticeLineParts objectAtIndex:1] floatValue], 
             [[verticeLineParts objectAtIndex:2] floatValue], 
             [[verticeLineParts objectAtIndex:3] floatValue]); 
     [vertices addObject:[[NSData alloc] initWithBytes:&c length:sizeof(c)]]; 

這似乎工作正常。輸出中的前幾個對象:

2010-10-18 14:18:08.237 ObjLoader[3778:207] (
    <5d1613bd 13f3da3f 8ac745bd>, 
    <f04c28bd 13f3da3f d88048bd>, 
    <649427bd d61ddb3f d88048bd>, 
    <477625bd d845db3f d88048bd>, 
    <4c1722bd 1668db3f d88048bd>, 

說到將它們從陣列中拉出之後將它們打印出來,沒有那麼多。有問題的代碼:

for (int i = 0; i < [vertices count]; i++) { 
    Coordinate c; 
    fillCoordinateFromData(c, [vertices objectAtIndex:i]); 
    NSLog(@"%@", CoordinateToNSString(c)); 
} 

[snip] 

void fillCoordinateFromData(Coordinate c, NSData *d) { 
    void *bytes = malloc(12); 
    [d getBytes:bytes]; 
    memcpy((void *)&c, &bytes, 12); 
    free(bytes); 
} 

當然,問題的輸出:

2010-10-18 14:22:00.692 ObjLoader[3825:207] 9.885923, -6.837428, 0.000000 
2010-10-18 14:22:00.693 ObjLoader[3825:207] 9.885923, -6.837428, 0.000000 
2010-10-18 14:22:00.694 ObjLoader[3825:207] 9.885923, -6.837428, 0.000000 
2010-10-18 14:22:00.695 ObjLoader[3825:207] 9.885923, -6.837428, 0.000000 
2010-10-18 14:22:00.695 ObjLoader[3825:207] 9.885923, -6.837428, 0.000000 

我認爲這是由人誰不是一個C精靈,有點像魔法師的學徒試圖Ç巫術所致。我認爲這應該是第99個學位的巫師顯而易見的,或者如果有人可以建議更現代的方式來做到這一點,讓我知道。

感謝, 威爾

回答

10
void fillCoordinateFromData(Coordinate c, NSData *d) { 

這傳遞c的價值。此函數中c的修改不會反映給調用者。

您需要傳遞指針(引用)。

fillCoordinateFromData(&c, [vertices objectAtIndex:i]); 

void fillCoordinateFromData(Coordinate* pc, NSData *d) { 
    void *bytes = malloc(12); 
    [d getBytes:bytes]; 
    memcpy((void *)c, &bytes, 12); 
    free(bytes); 
} 

但是最好只返回座標。

Coordinate c = getCoordinateFromData([vertices objectAtIndex:i]); 

Coordinate getCoordinateFromData(NSData* d) { 
    Coordinate c; 
    [d getBytes:&c]; // and let's not waste time allocating 12 bytes. 
    return c; 
} 

順便說一句,通過常規結構被包裹在NSValue,不NSData的。

[vertices addObject:[NSValue valueWithBytes:&c withObjCType:@encode(Coordinate)]]; 

Coordinate getCoordinateFromData(NSValue* d) { 
    Coordinate c; 
    [d getValue:&c]; 
    return c; 
}