【发布时间】:2013-06-25 13:22:31
【问题描述】:
我正在研究这个波前 obj 加载器示例:https://github.com/jlamarche/iOS-OpenGLES-Stuff/tree/master/Wavefront%20OBJ%20Loader
为了提高对象加载速度——我决定将加载的对象编码为 NSValue,然后存储在核心数据中。稍后,当需要再次显示相应的对象时 - 我从数据库中获取必要的 nsvalue 并取消归档它。
一切正常,但问题是 - 它没有我希望的那么快。
其中一个原因 - 因为在该示例中使用了结构对象。
我没有成功对它们进行编码/解码,所以我使用了 NSMutableArray,我在其中写入了所有结构数据,然后 - 我遍历它以将值放回结构对象。
比如有struct:
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"];
但它不起作用 - 如果成功编码,则在解码时 - 值不正确。
例如,我如何放回 struct 必要值的数组:
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 = 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;
并用作struct数组(我不知道它是如何真正调用的):
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];
可能是什么问题?
【问题讨论】:
-
您要编码单个结构还是该结构的数组? “不工作”是什么意思?
-
结构数组。不工作 - 就像 - 如果成功编码,那么解码时随机不正确的值。
标签: iphone objective-c opengl-es struct