PPSSignatureView 崩溃

Crash in PPSSignatureView

我正在使用 Xcode 6 为 iOS 7 开发应用程序。我从 GitHub 下载的 PPSSignatureView 组件有问题。我在弹出窗口中显示签名视图。签名视图第一次显示它工作正常,一切都很好。但是当我第二次重新显示相同的弹出窗口时,我在 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() returns 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];
}

我能够在 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/storyboards 声明它,您可能需要在打开新视图之前在事件上清除它。我仍然不确定我是否 100% 理解了这一点;如果有人对此有什么建议,请发表评论。

我通过添加调用

修复了错误
[signatureView erase]

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

初始化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];

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