【发布时间】:2019-02-28 13:47:13
【问题描述】:
我正在使用 CoreGraphics 画一条线。我刚刚更新了 Xcode 10 和 iOS 12。在 iOS 12 中,我的应用程序崩溃了。虽然,它在 iOS 11.4.1 及之前的版本中仍然运行良好。我无法解决问题。请在下面找到我的代码
-(void)drawRect:(CGRect)rect
{
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextSetShadow(context, CGSizeMake(-16.00, -5.0f), 5.0f);
CGContextStrokePath(context);
[super drawRect:rect];
[curImage release];
}
下面是touchesMoved方法。
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
previousPoint2 = previousPoint1;
previousPoint1 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
// calculate mid point
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(path);
CGPathRelease(path);
CGRect drawBox = bounds;
//Pad our values so the bounding box respects our line width
drawBox.origin.x -= self.lineWidth * 2;
drawBox.origin.y -= self.lineWidth * 2;
drawBox.size.width += self.lineWidth * 4;
drawBox.size.height += self.lineWidth * 4;
UIGraphicsBeginImageContext(drawBox.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
curImage = UIGraphicsGetImageFromCurrentImageContext();
[curImage retain];
UIGraphicsEndImageContext();
[self setNeedsDisplayInRect:drawBox];
}
CGPoint midPoint(CGPoint p1, CGPoint p2)
{
return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
previousPoint1 = [touch previousLocationInView:self];
previousPoint2 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
[self touchesMoved:touches withEvent:event];
}
问题是[self.layer renderInContext:context]; 的(void)drawRect:(CGRect)rect 函数的代码崩溃。 drawRect 函数调用时间过长(约 5000 次)和内存过载(约 20Gb)导致应用程序崩溃。
iOS 12 和 Xcode 10 会不会有变化?
我修复了这个问题。 更新我的新 toucheMoved() 函数:
- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
previousPoint2 = previousPoint;
previousPoint = [touch previousLocationInView:self];
location = [touch locationInView:self];
CGPoint mid1 = midPoint(previousPoint, previousPoint2);
CGPoint mid2 = midPoint(location, previousPoint);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, previousPoint.x, previousPoint.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(path);
CGPathRelease(path);
CGRect drawBox = bounds;
drawBox.origin.x -= self.lineWidth * 2;
drawBox.origin.y -= self.lineWidth * 2;
drawBox.size.width += self.lineWidth * 4;
drawBox.size.height += self.lineWidth * 4;
UIGraphicsBeginImageContextWithOptions(totalDrawBox.size, self.opaque, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform affineMoveLeftTop = CGAffineTransformMakeTranslation(-(int)totalDrawBox.origin.x, -(int)totalDrawBox.origin.y);
CGContextConcatCTM(context, affineMoveLeftTop);
float iOSVersion = [[UIDevice currentDevice].systemVersion floatValue];
if (iOSVersion >= 12) {
[self setNeedsDisplay];
} else {
[self.layer renderInContext: context];
}
curImage = UIGraphicsGetImageFromCurrentImageContext();
CGContextStrokePath(context);
UIGraphicsEndImageContext();
}
【问题讨论】:
-
与我的问题相同。你修好了吗?
-
@trungduc 似乎它们不是同一个问题,它在 iOS12 之前的我的应用程序中运行良好。仅在 iOS12 中崩溃。这很奇怪。
renderInContext会一直调用 drawRect 直到内存过载,然后在 iOS12 中崩溃。 -
嗨!我刚刚遇到了同样的问题。你修好了吗?
-
@Matthieu:我修好了。在 touchMoved() 函数中。我打电话给
[self setNeedsDisplay]而不是renderInContext。我只在 drawRect() 函数中使用renderInContext
标签: objective-c iphone core-graphics xcode10 ios12