Why would this report an invalid context?
<Error>: CGContextSaveGState: invalid context 0x0. This is a serious error.
This application, or a library it uses, is using an invalid context and is
thereby contributing to an overall degradation of system stability and
reliability. This notice is a courtesy: please fix this problem. It will
become a fatal error in an upcoming update.
This occurs on the call to drawInRect
in a category method on UIImage:
- (UIImage *)myImagePaddedToSize:(CGSize)newSize {
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
CGSize oldSize = self.size;
CGRect rect = (CGRect){
{
floorf((newSize.width-oldSize.width)/2),
floorf((newSize.height-oldSize.height)/2)
},
oldSize
};
[self drawInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
My understanding is that UIGraphicsBeginImageContextWithOptions
establishes a context that I draw in. And this seems to usually be the care, but very rarely I get this failure instead.
This is with the iOS 7 simulator included with Xcode 5.1.1.
(Initially, I thought this was a dupe of How can I fix CGContextRestoreGState: invalid context 0x0. It isn't; the message is different, and this one has an easy fix.)
In the cases where this error is occurring, newSize
has a height
and/or width
of 0 (or negative).
UIGraphicsBeginImageContextWithOptions
fails in this case, but it isn't shaped in a way that it can return an error. (There's no return or result.) Thus, you'll get this error instead as soon as you try to draw in the context that you weren't able to create.
To test for this, add a couple lines:
- (UIImage *)myImagePaddedToSize:(CGSize)newSize {
NSParameterAssert(newSize.width > 0);
NSParameterAssert(newSize.height > 0);
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
Give that a try. My guess is that it crashes in a few minutes of testing.
If this is indeed what's happening, you'll want to put in a permanent fix instead like so:
- (UIImage *)myImagePaddedToSize:(CGSize)newSize {
if ((newSize.width <= 0) || (newSize.height <= 0)) {
return nil;
}
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
The idea is that you can't pad an image to a zero or negative size, so just return nil
.