我有自定义 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 (nonatomic) CGImageRef renderedSymbol;
@property (nonatomic, strong) NSOperationQueue *queue;
@property (nonatomic, strong) NSString *symbol; // used in custom drawing
属性的自定义设置器/获取器:
-(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;
}
我能做些什么?