在背景中绘图

时间:2014-03-11 23:16:46

标签: ios multithreading cgcontext

我有一个IOS应用程序需要更新视图以响应用户或外部事件。绘制时间可以非常短或很长(几秒钟),具体取决于视图中的内容。

现在,绘图发生在视图的drawRect方法中当绘图很长并且有很多用户交互时,应用程序变得无法响应。

需要更新时,需要更新整个视图。如果在绘图过程中出现更改,则重新启动绘图以考虑更改是有意义的。

我想在后台绘图。

我的问题是在IOS中这样做的最佳机制是什么?

线程,NSOperation?

如何处理绘图?例如,如何在线程中为我正在更新的视图获取图形上下文?

如何开始绘图操作?现在我正在做setNeedsDisplay。我可以改变做其他事情。

有问题的视图位于UIScrollView中,但没有其他用户交互。

2 个答案:

答案 0 :(得分:2)

这是一个开始的框架。该代码假定输出视图是UIImageView。后台任务使用位图内存上下文为输出视图创建新图像。当后台绘制任务完成时,主线程将生成的图像分配给UIImageView。

sequenceNumber用于丢弃在绘制完成之前已过期的图像。一个可能的问题是事件很快到达,每个图像在完成之前已经过时。解决这个问题留给读者练习。

@interface SomeClass()
@property (weak, nonatomic) IBOutlet UIImageView *someView;
@property (nonatomic) int64_t sequenceNumber;
@end

@implementation SomeClass

- (UIImage *)createImageUsingBitmapMemoryContextOfSize:(CGSize)size
{
    // create the memory bitmap context
    UIGraphicsBeginImageContext( size );
    CGContextRef context = UIGraphicsGetCurrentContext();

    // draw something
    [[UIColor blueColor] set];
    CGContextFillEllipseInRect( context, CGRectMake(0, 0, size.width, size.height) );

    // create a UIImage 
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // return the image
    return( result );
}

// Note: the following function should only be called on the main thread
- (void)updateInResponseToSomeEvent
{
    self.sequenceNumber++;
    int64_t sequenceNumber = self.sequenceNumber;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^
    {
        UIImage *image = [self createImageUsingBitmapMemoryContextOfSize:self.someView.bounds.size];
        dispatch_async( dispatch_get_main_queue(), ^
        {
            if ( sequenceNumber == self.sequenceNumber )
                self.someView.image = image;
        });
    });
}

答案 1 :(得分:-1)

不要在后台绘制你的视图,因为UIKit不是线程安全的!在后台,您可以绘制到图像,并在绘制完成后,在主线程中更新您的视图。

相关问题