线程安全的CGContext绘图

拜读了《iOS 7Progaramming Pushing the Limits》( 中文版挫名《iOS编程实战》),受益匪浅。
结合自己的踩坑经历,分享下Quartz(Core Graphics)框架里的绘图上下文,CGContextRef。
OK,我们常用UIGraphicsGetCurrentContext();去获取上下文,这是一个线程不安全的方法,但当踩坑之前,我是不知道的,相信也有很多人也像我一样(当然UI开头的一般都要在主线程中执行)。

好,我的坑是这样的,我在另一个线程里,获取了上下文并开始绘图,blabla...,它有时会如期运行,有时不会,好了,这明显线程问题,解决方法是这样的。

UIGraphicsGetCurrentContext()获取的是当前上下文,如果有两个或两个以上(其中一个可能是主线程)的线程同时使用它,你就会遇到这种问题。
CGBitmapContextCreate方法,这是一个线程安全的方法,使用它创建上下文,使用完时,并用CGContextRealse释放它(即使开启ARC这也是需要的,当然我相信大家都知道)。但这个方法略显复杂(相比起UIGraphicsGetCurrentContext),你需要知道每个颜色空间有多少个字节,每行有多少个字节,当然这不是你想要的,每次当你创建的时候,都执行这个冗长的方法,所以这里封装了方法。(需要注意TLO坐标系,和LLO坐标系的区别)

CG_INLINE UIImage* UIGraphicsGetImageFromContext(CGContextRef ctx)
{
	CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
	UIImage* image = [UIImage imageWithCGImage:cgImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
	CGImageRelease(cgImage);

	return image;
}

所以现在,新需求出现了,我们不能通过UIGraphicsGetImageFromCurrentImageContext()方法获取UIImage了,需要从指定的上下中获取图片。避免冗长,这里同样做了一层封装。

CG_INLINE UIImage* UIGraphicsGetImageFromContext(CGContextRef ctx)
{
	CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
	UIImage* image = [UIImage imageWithCGImage:cgImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
	CGImageRelease(cgImage);

	return image;
}
好了,现在我们可以很简单的在一个矩形区域内,自定义绘制一张图片。
CGContextRef ctx = CGContextCreate(CGSizeMake(100, 100));
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextFillRect(ctx, CGRectMake(0, 0, 100, 100));
UIImage* image = UIGraphicsGetImageFromContext(ctx);
CGContextRelease(ctx);

有兴趣,可以关注我微博 @Taligent
更希望可以推荐给我好的文章,共同进步...


你可能感兴趣的:(iOS)