【发布时间】:2014-11-21 14:54:49
【问题描述】:
我正在制作一个应用程序,我想在其中绘制很多形状 - 圆形、方框、线条等。 数以百万计。
为了测试它的性能,我把这个简单的 UIView 放在一起。请注意,信用到期 - 我受到 this project 的启发。
import UIKit
let qkeyString = "label" as NSString
var QKEY = qkeyString.UTF8String
let qvalString = "com.hanssjunnesson.Draw" as NSString
var QVAL = qvalString.UTF8String
public class RenderImageView: UIView {
var bitmapContext: CGContext?
let drawQueue: dispatch_queue_attr_t = {
let q = dispatch_queue_create(QVAL, nil)
dispatch_queue_set_specific(q, QKEY, &QVAL, nil)
return q
}()
public override init() {
super.init()
render()
}
required public init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
render()
}
override required public init(frame: CGRect) {
super.init(frame: frame)
render()
}
public override func drawRect(rect: CGRect) {
if let bitmapContext = self.bitmapContext {
let context = UIGraphicsGetCurrentContext()
let image = CGBitmapContextCreateImage(bitmapContext)
CGContextDrawImage(context, self.bounds, image)
}
}
private func render() {
dispatch_async(drawQueue) {
let startDate = NSDate()
let bounds = self.bounds
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
self.bitmapContext = context
CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor)
CGContextFillRect(context, bounds)
CGContextSetFillColorWithColor(context, UIColor(red: 0.15, green: 0.4, blue: 0.8, alpha: 1.0).CGColor)
for i in 1...1000000 {
CGContextFillEllipseInRect(context, bounds)
}
UIGraphicsEndImageContext()
self.setNeedsDisplay()
let benchmark = startDate.timeIntervalSinceNow
println("Rendering took: \(-benchmark*1000) Ms")
}
}
}
这很好用。在我的 iOS 模拟器上,绘制一百万个圆圈只需要一分钟多一点的时间。
我想加快速度,所以我尝试从多个线程绘制位图上下文。
let group = dispatch_group_create()
for i in 1...100 {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) {
dispatch_group_enter(group)
CGContextFillEllipseInRect(context, bounds)
dispatch_group_leave(group)
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
但是,这不起作用。我在拨打CGContextFillEllipseInRect(context, bounds) 时收到EXC_BAD_ACCESS。
在后台线程中绘制到 CGContext 似乎没问题,只要它与创建它的线程相同。
有人知道如何让它工作吗?
【问题讨论】:
-
如果不重用
context引用,而是获取当前位图上下文会怎样? -
获取位图上下文的唯一方法是在创建新的图像上下文后调用 UIGraphicsGetCurrentContext。否则, UIGraphicsGetCurrentContext 将获得另一个上下文。绘图不会显示在结果图像中。
标签: ios objective-c cocoa swift core-graphics