我正在研究这个波前 obj 加载器示例:https ://github.com/jlamarche/iOS-OpenGLES-Stuff/tree/master/Wavefront%20OBJ%20Loader
为了提高对象加载速度——我决定将加载的对象编码为 NSValue,然后存储在核心数据中。稍后,当需要再次显示相应的对象时 - 我从数据库中获取必要的 nsvalue 并取消归档它。
一切正常,但问题是 - 它没有我希望的那么快。
原因之一 - 因为在该示例中使用了 struct 对象。
我没有成功对它们进行编码/解码,所以我使用了 NSMutableArray,我在其中写入了所有结构数据,然后 - 我遍历它以将值放回结构对象。
例如,有结构:
typedef struct {
GLfloat x;
GLfloat y;
GLfloat z;
} Vertex3D;
然后定义:
typedef Vertex3D Vector3D;
但在 OpenGLWaveFrontObject 类中,它是这样使用的:
Vector3D *vertexNormals;
我怎样才能像这样编码/解码结构?
我试过这样:
[coder encodeObject:[NSValue value:&vertexNormals withObjCType:@encode(Vector3D)] forKey:@"vertexNormals"];
或像这样:
[coder encodeObject:[NSValue value:&vertexNormals withObjCType:@encode(Vector3D[30])] forKey:@"vertexNormals"];
但它不起作用 - 如果成功编码,那么在解码时 - 值不正确。
例如,我如何放回结构必要值的数组:
vertices = malloc(sizeof(Vertex3D) * [verticesArray count]);
for(int i = 0; i < [verticesArray count]; i++)
{
vertices[i].x = [[[verticesArray objectAtIndex:i] objectAtIndex:0] floatValue];
vertices[i].y = [[[verticesArray objectAtIndex:i] objectAtIndex:1] floatValue];
vertices[i].z = [[[verticesArray objectAtIndex:i] objectAtIndex:2] floatValue];
}
这行得通,但我有更多的结构数组,如果数组很大 - 这将成为一个大问题。
编辑:
使用Amin Negm-Awad提供的答案:
如果我只是将 NSArchiver 更改为 NSKeyedArchiver - 它会引发错误:
[NSKeyedArchiver encodeArrayOfObjCType:count:at:]: unsupported type "{?=fff}]" for array encoding'
当我尝试:
NSValue *encapsulated = [NSValue valueWithBytes:vertexNormals objCType:@encode(Vertex3D[3])];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:encapsulated];
[coder encodeObject:data forKey:@"vertexNormals"];
并创建了 vertexNormals:
vertexNormals = calloc(3, sizeof(Vector3D));
并填写了您提供的类似数据。
编辑2:
使用 Amin Negm-Awad 提供的更新答案,
我成功地将结构对象存储为 NSData 并对其进行编码,然后对其进行解码。有用!
例如,这样它也可以帮助其他人:
//Encode
NSData *verticesData = [NSData dataWithBytes:vertices length:numberOfVertices * sizeof(Vector3D)];
[coder encodeObject:verticesData forKey:@"vertices"];
//Decode
vertices = malloc(sizeof(Vertex3D) * numberOfVertices);
NSData *verticesData = [decoder decodeObjectForKey:@"vertices"];
[verticesData getBytes:vertices length:sizeof(Vertex3D) * numberOfVertices];
其中 Vertex3D 是一个结构:
typedef struct {
GLfloat x;
GLfloat y;
GLfloat z;
} Vertex3D;
并用作结构数组(我不知道它是如何真正调用的):
Vertex3D *vertices;
不幸的是,我无法存储纹理数据。我可以编码和解码,但解码后的数据总是随机离奇。
我以这种方式声明它:
GLfloat *textureCoords;
我以这种方式编码/解码:
//Encode
NSData *textureCoordsData = [NSData dataWithBytes:textureCoords length:valuesPerCoord * numberOfVertices];
[coder encodeObject:textureCoordsData forKey:@"textureCoords"];
//Decode
textureCoords = malloc(sizeof(GLfloat) * valuesPerCoord * numberOfVertices);
NSData *textureCoordsData = [decoder decodeObjectForKey:@"textureCoords"];
[textureCoordsData getBytes:textureCoords length:valuesPerCoord * numberOfVertices];
可能是什么问题呢?