UIGraphicsGetImageFromCurrentImageContext crash when using a queue

727 views Asked by At

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);
1

There are 1 answers

3
matt On

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.