我有自定义UICollectionViewCell子类,可以在其中进行剪切,描边和透明绘制。它在Simulator和iPhone 5上运行良好,但在较旧的设备上存在明显的性能问题。

因此,我想将耗时的图形移至后台线程。由于-drawRect方法总是在主线程上调用,因此我最终将绘制的上下文保存到CGImage(原始问题包含使用CGLayer编写的代码,但正如Matt Long所指出的那样,已经过时了)。

这是我在此类内的drawRect方法的实现:

-(void)drawRect:(CGRect)rect {

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    if (self.renderedSymbol != nil) {
        CGContextDrawImage(ctx, self.bounds, self.renderedSymbol);
    }
}

定义此renderSymbol属性的渲染方法:
- (void) renderCurrentSymbol {

    [self.queue addOperationWithBlock:^{

// creating custom context to draw there (contexts are not thread safe)
        CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
        CGContextRef ctx = CGBitmapContextCreate(nil, self.bounds.size.width, self.bounds.size.height, 8, self.bounds.size.width * (CGColorSpaceGetNumberOfComponents(space) + 1), space, kCGImageAlphaPremultipliedLast);
        CGColorSpaceRelease(space);

// custom drawing goes here using 'ctx' context

// then saving context as CGImageRef to property that will be used in drawRect
        self.renderedSymbol = CGBitmapContextCreateImage(ctx);

// asking main thread to update UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [self setNeedsDisplayInRect:self.bounds];
        }];

        CGContextRelease(ctx);

    }];
}

此设置在主线程上可以很好地工作,但是当我用NSOperationQueue或GCD包装它时,会收到很多不同的“无效上下文0x0 ”错误。应用程序本身不会崩溃,但不会发生绘图。我想发布自定义创建的CGContextRef会有问题,但是我不知道该怎么办。

这是我的属性(property)声明。 (我尝试使用原子版本,但这无济于事)
@property (nonatomic) CGImageRef renderedSymbol;
@property (nonatomic, strong) NSOperationQueue *queue;
@property (nonatomic, strong) NSString *symbol; // used in custom drawing

属性的自定义 setter / getter :
-(NSOperationQueue *)queue {
    if (!_queue) {
        _queue = [[NSOperationQueue alloc] init];
        _queue.name = @"Background Rendering";
    }
    return _queue;
}
-(void)setSymbol:(NSString *)symbol {
    _symbol = symbol;
    self.renderedSymbol = nil;
    [self setNeedsDisplayInRect:self.bounds];
}

-(CGImageRef) renderedSymbol {
    if (_renderedSymbol == nil) {
        [self renderCurrentSymbol];
    }
    return _renderedSymbol;
}

我能做些什么?

最佳答案

您是否注意到自2006年以来没有更新过您所引用的CGLayer上的文档?您已经假设CGLayer是正确的解决方案是不正确的。苹果公司几乎已经放弃了这项技术,您可能也应该这样做:http://iosptl.com/posts/cglayer-no-longer-recommended/使用Core Animation。

关于ios - 用CGImage/CGLayer绘制另一个线程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16545001/

10-09 20:31