Objective-C - 复制退出(0)并修复EXC_BAD_ACCESS

时间:2012-07-17 11:35:28

标签: objective-c ios opengl-es exc-bad-access

我的最新应用程序遇到了一些令人沮丧的问题!!

我正在使用OpenGLES 1将模型绘制到不断更新的屏幕上,然后您可以截取并分享您喜欢的内容,之后您可以返回应用程序开始屏幕并重新开始。

在应用程序第一次运行时,似乎一切正常,没有崩溃。但是如果你经历过一次然后尝试再次通过,一旦OpenGLES绘图视图必须开始绘制元素,它就会在我的EXC_BAD_ACCESS行上引发glDrawElements错误。

我现在放弃尝试修复此错误,过去两周我没有运气!!

我已经在我的plist中设置了属性,以便应用程序不在后台运行,每当我运行一次,然后退出它并再次加载它将再次完全运行。

所以我想知道的是,如果我能以某种方式模拟exit(0)功能的功能,但实际上没有退出应用程序?

因此,实质上,每次用户从共享页面导航回主页时,应用程序都会运行exit代码,让应用程序再次从头开始运行。

至少在我看来,这对于处理这种情况并不是一个很好的方法,但我需要快速的结果,这似乎是一个很好的方法,直到我能够达到实际的底部错误。

谢谢,

马特

编辑1:我不打算将这个应用程序放在商店中,这只是暂时的事情。

编辑2:发布的代码包含我的绘制功能,采用并改编自Bill Dudney's WaveFront .obj loader

for(WaveFrontOBJGroup *group in scene.groups)
{
    NSString *matPath = [NSString stringWithFormat:@"%@%@.mtl", materialName, modelPart];
    NSArray *materialArray = [WaveFrontOBJMaterial materialsFromLibraryFile:matPath];
    WaveFrontOBJMaterial *mat = [materialArray objectAtIndex:0];

    if(group.smoothing)
        glShadeModel(GL_SMOOTH);
    else
        glShadeModel(GL_FLAT);

    // load (if necessary) and bind the vertices
    GLuint verticesName = [group verticesName:GL_STATIC_DRAW];
    glBindBuffer(GL_ARRAY_BUFFER, verticesName);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    // load (if necessary) and bind the normals
    GLuint normalsName = [group normalsName:GL_STATIC_DRAW];
    glBindBuffer(GL_ARRAY_BUFFER, normalsName);
    glNormalPointer(GL_FLOAT, 0, 0);

    ColorRGBA color = mat.ambientColor;
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)&color);
    color = mat.diffuseColor;
    if(alpha)
        glColor4f(color.red, color.green, color.blue, mat.disolve);
    else
        glColor4f(color.red, color.green, color.blue, color.alpha);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)&color);
    color = mat.specularColor;
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)&color);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mat.shine);

    // load (if necessary) and bind the texture
    if(group.textureCoordinatesIndexData.length > 0)
    {
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        GLuint textureCoordsName = [group textureCoordinatesName:GL_STATIC_DRAW];
        glEnable(GL_TEXTURE_2D);
        glBindBuffer(GL_ARRAY_BUFFER, textureCoordsName);
        glTexCoordPointer([group texCoordSize], GL_FLOAT, 0, 0);
        GLuint texId = [mat.diffuseTexture textureName];
        glBindTexture(GL_TEXTURE_2D, texId);
    }

    GLuint indexesName = [group indexesName:GL_STATIC_DRAW];
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexesName);

    glDrawElements(GL_TRIANGLES, group.indexCount, GL_UNSIGNED_SHORT, NULL);
    //^^This line above is where I get the "EXC_BAD_ACCESS" message

    if(group.textureCoordinatesIndexData.length > 0)
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

我已经通过断点和NSLog检查了group.indexCount并且它不是空的,它与第一次运行时的工作方式完全相同。

我意识到它不一定就在那条线上,我听说过其他关于它是由于变量没有被初始化为指针 - * - 或NSStrings没有匹配的标识符和值{{1但我在代码中没有看到任何内容,当然我很容易错过一个。

2 个答案:

答案 0 :(得分:0)

记住两件事:

1)您的主ViewController中有一个方法-(void)viewWillAppear:(BOOL)animated。当用户返回此屏幕时(不像viewDidLoad),这将调用always(!)。

2)如果你甚至像你描述的那样做,你可能没有进入AppStore!

答案 1 :(得分:0)

我不确定为什么你的应用程序不能在模拟器上编译,但你应该尝试适当地链接你的库,以便你可以启动并运行 - 没有什么比僵尸更糟糕的访问错误。

如果您知道您的错误是来自glDrawElements,那么您应该查看传递给它的内容。 This link也许可以帮到你。

你仍然在应用程序中无法获得退出应用程序的“功能”的原因是因为它不是应用程序的功能 - 它是操作系统丢弃与应用程序相关的所有内容然后重新加载它。根据定义,如果不实际关闭,您将无法执行此操作。

但是,如果您的问题由此解决,那么您的设置中可能需要重做(初始化,声明等)。检查是什么设置为nil或丢弃,然后重新设置。

在不查看代码的情况下,我无法确切地说出这一点,但您可以编写一种覆盖/重新初始化所有当前变量的方法。这可能会复制退出所需应用程序的部分。