为iOS性能问题绘制应用程序

我正在为iOS创build绘图应用程序。 通过触摸来绘制东西我使用了本教程中的代码: http : //www.raywenderlich.com/18840/how-to-make-a-simple-drawing-app-with-uikit

我用于绘制的代码如下所示:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { mouseSwiped = NO; UITouch *touch = [touches anyObject]; lastPoint = [touch locationInView:self.view]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { mouseSwiped = YES; UITouch *touch = [touches anyObject]; CGPoint currentPoint = [touch locationInView:self.view]; UIGraphicsBeginImageContext(self.view.frame.size); [self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush ); CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0); CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal); CGContextStrokePath(UIGraphicsGetCurrentContext()); self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext(); [self.tempDrawImage setAlpha:opacity]; UIGraphicsEndImageContext(); lastPoint = currentPoint; NSLog(@"Moved"); } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if(!mouseSwiped) { UIGraphicsBeginImageContext(self.view.frame.size); [self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush); CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, opacity); CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); CGContextStrokePath(UIGraphicsGetCurrentContext()); CGContextFlush(UIGraphicsGetCurrentContext()); self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } UIGraphicsBeginImageContext(self.mainImage.frame.size); [self.mainImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0]; [self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:opacity]; self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext(); self.tempDrawImage.image = nil; UIGraphicsEndImageContext(); } 

我的问题是这样的:这个代码在模拟器和我的iPhone 5上工作良好,但是当我在iPad 2上运行它时,它工作不正常。 我的意思是当触摸被移动时,它每隔3秒或者类似的东西(它不是连续的)被画在屏幕上。 此外,当我不停地移动手指而没有解除我的手指应用程序崩溃之后。

我想这是一个性能问题。 但为什么? 你有什么想法,我该如何解决它?

问题是你一直在调用[self.tempDrawImage.image drawInRect:] 。 这个调用在CPU上渲染图像,速度非常慢。 您不必要地开始和结束图像上下文。 使用这个代码,我testing了它在iPad 2上,它工作顺利。

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { mouseSwiped = NO; UITouch *touch = [touches anyObject]; lastPoint = [touch locationInView:self.view]; UIGraphicsBeginImageContext(self.view.frame.size); } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { mouseSwiped = YES; UITouch *touch = [touches anyObject]; CGPoint currentPoint = [touch locationInView:self.view]; CGContextRef ctxt = UIGraphicsGetCurrentContext(); CGContextMoveToPoint(ctxt, lastPoint.x, lastPoint.y); CGContextAddLineToPoint(ctxt, currentPoint.x, currentPoint.y); CGContextSetLineCap(ctxt, kCGLineCapRound); CGContextSetLineWidth(ctxt, brush ); CGContextSetRGBStrokeColor(ctxt, red, green, blue, 1.0); CGContextSetBlendMode(ctxt,kCGBlendModeNormal); CGContextStrokePath(ctxt); self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext(); [self.tempDrawImage setAlpha:opacity]; lastPoint = currentPoint; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesCancelled:touches withEvent:event]; UIGraphicsEndImageContext(); if(!mouseSwiped) { self.tempDrawImage.image = nil; } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if(!mouseSwiped) { UIGraphicsEndImageContext(); UIGraphicsBeginImageContext(self.view.frame.size); [self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush); CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, opacity); CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); CGContextStrokePath(UIGraphicsGetCurrentContext()); CGContextFlush(UIGraphicsGetCurrentContext()); self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } UIGraphicsBeginImageContext(self.mainImage.frame.size); [self.mainImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0]; [self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:opacity]; self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext(); self.tempDrawImage.image = nil; UIGraphicsEndImageContext(); } 

是的,但有了这个,你将有一个内存问题…内存警告和崩溃。

如果你想尝试,画50到150行,你可以看到它是如何造成内存问题。

如果你想解决这个问题,在touchesEnded方法中将其更改为:

 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UIGraphicsEndImageContext(); //<----this is correct if(!mouseSwiped) { //UIGraphicsEndImageContext(); <--- this is the issue 

然后完美的工作!