Reputation: 993
I’m using Xcode 6 to develop an app for iOS 7. I’m having an issue with the PPSSignatureView
component downloaded from GitHub. I’m presenting the signature view in a popover. The first time the signature view displays it works and everything is fine. But when I redisplay the same popover a 2nd time, I get an error in 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)++;
}
On the 2nd presentation, glMapBufferOES()
returns NULL
and memcpy()
generates the error
Thread 1:EXC_BAD_ACCESS(code=1, address=0x0)
I do not know the OpenGL library. I have read some SO entries about OpenGL, Xcode 6 and iOS8, but those issues refer to compile time errors and I am having a run time error. Does anyone understand what is going on?
Thanks
Edit: I know the error looks like a low-memory error. I'm not getting a memory warning from iOS and I'm having trouble believing that's the real problem. Also, on the second and subsequent presentations, if I do a long press on the signature view before I start drawing then the signature view does not crash. But calling the long press action in code on the second presentation does not prevent the crash.
Here's the long press code:
- (void)longPress:(UILongPressGestureRecognizer *)lp {
[self erase];
}
- (void)erase {
length = 0;
dotsLength = 0;
self.hasSignature = NO;
[self setNeedsDisplay];
}
Upvotes: 1
Views: 667
Reputation: 376
I was able to recreate your exact error message on iOS8. As the message is unclear, it may be the same error that I received as a result of a different issue.
I was opening my view by code:
EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
PPSSignatureView *sign = [[PPSSignatureView alloc] initWithFrame:CGRectMake(10, 10, 500, 300) context:context];
I noticed that if I changed the context to use kEAGLRenderingAPIOpenGLES3 instead of kEAGLRenderingAPIOpenGLES2 I got your exact error.
Try using kEAGLRenderingAPIOpenGLES2 if you are not already:
EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
VS
EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3];
I also have a solution to the issue with loading the view (the 2nd time) on iOS8, and it is likely the same for iOS7.
From what I learnt, the context (EAGLContext
) does not get de-allocated after use. This causes it to error the next time it is called in the custom signature view.
My solution to this was to (before declaring the context) clear any existing context. I did that using the following code:
[EAGLContext setCurrentContext:nil]
EAGLContext *context = [EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
PPSSignatureView *sign = [[PPSSignatureView alloc] initWithFrame:CGRectMake(10, 10, 500, 300) context:context];
If you are declaring it though the UI/storyboards, you may need to clear it on an event before opening the new view. I am still not sure I understand this 100%; if anyone has advice on that, please leave a comment.
Upvotes: 0
Reputation: 993
I fixed the error by adding the call
[signatureView erase]
immediately after presenting the popover containing the signature view.
Upvotes: 1
Reputation: 11
When you init the PPSSignatureView, you can write like this:
[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];
I still don't know why this works, but this solved my problem.
Upvotes: 0