2015-06-18 2 views
0

Я пытаюсь понять, как сбой моего кода при использовании очереди, но работает при использовании основного потока. Этот код работает отлично:UIGraphicsGetImageFromCurrentImageContext сбой при использовании очереди

- (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]; 
} 

Но эта версия кода происходит сбой через некоторое время, когда incrementalImage = UIGraphicsGetImageFromCurrentImageContext(); называется.

- (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 определяются как Ивар, как это:

dispatch_queue_t drawingQueue; 

и инициализируется следующим образом:

drawingQueue = dispatch_queue_create("drawingQueue", NULL); 
+0

Сообщите подробности об аварии. – rmaddy

+0

Я не могу. Ошибка возникает только на устройстве, и Xcode не сломается в отладчике, когда это произойдет. Это просто сбой, и Xcode теряет соединение. –

+1

Возможно, вам захочется синхронизировать доступ к вашему ivan. – rmaddy

ответ

1

Вы говорите о прикосновениях. Вы говорите о представлении. Эти вещи не являются потокобезопасными. Вы не должны говорить о них в фоновом режиме. И вы говорите о своем свойстве incrementalImage на двух разных потоках. И это только очевидные опасности; есть и другие свойства.

+0

На самом деле это абсолютно безопасно использовать методы 'UIGraphincsBegin/EditImageContext' и' UIGraphicsGetImageFromCurrentImageContext' для любого потока. Он должен работать в целом. Вероятная проблема заключается в том, что 'incrementalImage' обновляется в фоновом режиме при обращении к основному потоку при обработке событий касания. – rmaddy

+0

Да, я рисую его в drawRect вот так: - (void) drawRect: (CGRect) rect { [incrementalImage drawInRect: rect]; } –

+0

@rmaddy Я не сказал, что что-то случилось с частью _drawing_ кода, содержащейся в фоновом потоке, не так ли? Мой ответ указал на другой материал. Я все время рисую фоном. Но я также кое-что знаю о том, что еще не делать. Я стараюсь не касаться свойств нескольких потоков, и я никогда не касаюсь ничего, что не является потокобезопасным и не принадлежит мне, как UITouch, в фоновом потоке. – matt