I'm trying to understand way my code crash when using a queue, but working when using the main thread. This code works fine:
- (void)penMoved:(NSSet *)touches {
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self];
CGPoint midPoint = midpoint(previousPoint, currentPoint);
CGRect bounds = self.bounds;
UIGraphicsBeginImageContextWithOptions(bounds.size, YES, [UIScreen mainScreen].scale);
[path addQuadCurveToPoint:midPoint controlPoint:previousPoint];
[incrementalImage drawAtPoint:CGPointZero];
[path stroke];
previousPoint = currentPoint;
incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setNeedsDisplay];
}
But this version of the code crashes after a while when incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
is called.
- (void)penMoved:(NSSet *)touches {
dispatch_async(drawingQueue, ^{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self];
CGPoint midPoint = midpoint(previousPoint, currentPoint);
CGRect bounds = self.bounds;
UIGraphicsBeginImageContextWithOptions(bounds.size, YES, [UIScreen mainScreen].scale);
[path addQuadCurveToPoint:midPoint controlPoint:previousPoint];
[incrementalImage drawAtPoint:CGPointZero];
[path stroke];
previousPoint = currentPoint;
incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
[self setNeedsDisplay];
});
});
}
drawingQueue is defined as an ivar like this:
dispatch_queue_t drawingQueue;
and initialized like this:
drawingQueue = dispatch_queue_create("drawingQueue", NULL);
You are talking about touches. You are talking about a view. Those things are not thread safe. You must not talk about them on a background thread. And you are talking about your
incrementalImage
property on two different threads. And that's just the obvious dangers; there are other properties in there too.