在NSArray中存储结构

wjl*_*wjl 5 c struct objective-c wavefront nsdata

回到我每天愚蠢的问题.今天我正在尝试在NSArray中放置一个结构.好吧,这很容易,将它包装在NSData中.如果你认识我,你知道你将会看到代码.在这个例子中,我将一个从Wavefront OBJ加载到结构中的顶点线并将其粘贴在一个数组中.

        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)]];
Run Code Online (Sandbox Code Playgroud)

这似乎工作正常.输出中的前几个对象:

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>,
Run Code Online (Sandbox Code Playgroud)

在从阵列中拉出它们之后将它们打印出来,而不是那么多.违规代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

当然,有问题的输出:

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
Run Code Online (Sandbox Code Playgroud)

我认为这是由一个不是C巫师的人尝试的C魔法造成的,有点像魔法师的学徒.我认为这对于99度的巫师来说应该是显而易见的,或者如果有人可以建议采用更现代的方式来做到这一点,请告诉我.

谢谢,威尔

ken*_*ytm 10

void fillCoordinateFromData(Coordinate c, NSData *d) {
Run Code Online (Sandbox Code Playgroud)

这通过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);
}
Run Code Online (Sandbox Code Playgroud)

但最好只返回坐标.

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;
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,按照惯例,结构包装在NSValue中,而不是NSData.

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

Coordinate getCoordinateFromData(NSValue* d) {
  Coordinate c;
  [d getValue:&c];
  return c;
}
Run Code Online (Sandbox Code Playgroud)