Если рисование вида занимает заметное количество времени, я бы рекомендовал нарисовать его в виде изображения в фоновом потоке при обновлении, и чтобы вид просто нарисовал изображение. Это предотвратит блокировку основного потока на длительное время.
Следующий код показывает, как создавать и рисовать в растровом контексте из фонового потока. Когда вы вызываете метод updateInBackground
, он создает новый фоновый поток, который создает и рисует в контексте, а затем создает изображение, используя этот контекст. Если вы поместите это в пользовательский подкласс UIImageView
, то изображение будет автоматически выведено на экран.
- (void)updateInBackground {
[self performSelectorInBackground:@selector(_drawInBackground:) withObject:[NSValue valueWithCGRect:self.bounds]];
}
- (void)_drawInBackground:(NSValue *)boundsValue {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
CGRect bounds = [boundsValue CGRectValue];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if(!colorSpace) {
[pool drain];
return;
}
CGContextRef context = CGBitmapContextCreate(NULL,bounds.size.width, bounds.size.height, 8, bounds.size.width * 32, colorSpace, kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);
if(!context) {
[pool drain];
return;
}
CGContextConcatCTM(context, CGAffineTransformMake(1,0,0,-1,0,bounds.size.height));
// do drawing here
CGImageRef image = CGBitmapContextCreateImage(context);
[self performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageWithCGImage:image] waitUntilDone:YES];
CGImageRelease(image);
CGContextRelease(context);
[pool drain];
}
При рисовании в фоновом потоке вы НЕ можете использовать объекты и методы UIKit. Все рисование должно быть выполнено с использованием Кварцевые функции . Если вам нужно использовать UIKit, фоновый поток может вызвать метод в основном потоке для выполнения этого раздела чертежа:
[self performSelectorOnMainThread:@selector(drawInMainThread:) withObject:[NSValue valueWithPointer:context] waitUntilDone:YES];
- (void)drawInMainThread:(NSValue *)value {
UIGraphicsPushContext((CGContextRef)[value pointerValue]);
// do drawing using UIKit
UIGraphicsPopContext();
}