PPSSignatureView崩溃

时间:2015-04-17 14:28:33

标签: ios xcode opengl-es

我正在使用Xcode 6为iOS 7开发应用程序。我遇到了从GitHub下载的PPSSignatureView组件的问题。我在popover中呈现签名视图。签名视图第一次显示它有效并且一切正常。但是当我第二次重新显示同一个弹出窗口时,我在PPSSignatureView.m

中收到错误
#import <OpenGLES/ES2/glext.h>

// Append vertex to array buffer
static inline void addVertex(uint *length, PPSSignaturePoint v) {
    if ((*length) >= maxLength) {
        return;
    }

    GLvoid *data = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
    memcpy(data + sizeof(PPSSignaturePoint) * (*length), &v, sizeof(PPSSignaturePoint));
    glUnmapBufferOES(GL_ARRAY_BUFFER);

    (*length)++;
}

在第二个演示文稿中,glMapBufferOES()返回NULLmemcpy()生成错误

Thread 1:EXC_BAD_ACCESS(code=1, address=0x0)

我不知道OpenGL库。我已经阅读了一些关于OpenGL,Xcode 6和iOS8的SO条目,但这些问题涉及编译时错误,我遇到了运行时错误。有谁知道发生了什么?

由于

编辑:我知道错误看起来像是一个低内存错误。我没有收到来自iOS的内存警告,而且我很难相信这是真正的问题。此外,在第二次和后续演示中,如果我在开始绘制之前长按签名视图,则签名视图不会崩溃。但是在第二个演示文稿中调用代码中的长按操作并不能防止崩溃。

这是长按代码:

- (void)longPress:(UILongPressGestureRecognizer *)lp {
    [self erase];
}


- (void)erase {
    length = 0;
    dotsLength = 0;
    self.hasSignature = NO;

    [self setNeedsDisplay];
}

3 个答案:

答案 0 :(得分:1)

感谢您的回复。我通过添加调用来修复错误

[signatureView erase]

在显示包含签名视图的弹出窗口后立即显示。

答案 1 :(得分:0)

我在尝试修复类似错误时收到了此问题的提醒,但我能够在iOS8上重新创建您的确切错误消息。由于消息不清楚,因为不同的问题导致我的错误相同。

我正在通过代码打开我的观点:

EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
PPSSignatureView *sign = [[PPSSignatureView alloc] initWithFrame:CGRectMake(10, 10, 500, 300) context:context];

我注意到如果我更改了上下文以使用 kEAGLRenderingAPIOpenGLES3 而不是 kEAGLRenderingAPIOpenGLES2 ,我得到了您的确切错误。

如果您尚未使用 kEAGLRenderingAPIOpenGLES2 ,请尝试使用。

EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2]; 

VS

EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3]; 

如果你已经用另一种方式解决了这个问题,请发布你的结果,因为我遇到了类似的问题,这可能会帮助我。

<强>更新

我找到了一个解决方案,在iOS8上加载视图(第二次)的问题,对于iOS7来说可能是相同的。

因此,根据我的学习情况,上下文(EAGLContext)在使用后不会被取消分配。这会导致下次在自定义签名视图中调用它时出错。

我对此的解决方案是(在声明上下文之前)清除任何现有的上下文。我使用以下代码完成了这项工作:

[EAGLContext setCurrentContext:nil]
EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
PPSSignatureView *sign = [[PPSSignatureView alloc] initWithFrame:CGRectMake(10, 10, 500, 300) context:context];

让我知道这是否适合其他人?如果您通过UI /故事板声明它,则可能需要在打开新视图之前清除事件。我仍然不确定我是否理解这100%如果有人有一些好的做法建议请发表评论。

答案 2 :(得分:0)

当您启动PPSSignatureView时,您可以这样写:

[EAGLContext setCurrentContext:nil];
EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
PPSSignatureView *sign = [[PPSSignatureView alloc] initWithFrame:CGRectMake(0, 0, self.view.height, self.view.width) context:context];

我仍然不知道为什么会这样,但这解决了我的问题。