我正在使用CATiledLayer支持的NSView(Mac而不是iOS)并且根据Apple文档https://developer.apple.com/reference/quartzcore/catiledlayer我希望在多个线程上异步调用它以帮助提高性能,但它似乎只是被调用主线。
我正在drawLayer(layer: CALayer, inContext ctx: CGContext)
我在NSView上启用了canDrawConcurrently
,并确保窗口allowsConcurrentViewDrawing
设置为true(默认值),但它仍然总是调用每个tile rect的主线程。
我需要在显示之前进行一些图像处理,这取决于需要显示的矩形区域,并且在主线程上运行会影响性能。
我是如何强迫它在后台线程上调用的?
我尝试将操作编组到后台线程上,然后使用以下内容调用主队列,但它显示一个空白的矩形:
backgroundQueue.addOperationWithBlock({ [ weak self ] in
guard let strongSelf = self else { return }
// ** This is the part I nee to do in background that can take some time
guard let image = strongSelf.imageForTileRect(layerBounds, imageSize: imageSize) else { return }
// ** End background bit
var rect = layerBounds
let rectImageRef = image.CGImageForProposedRect(&rect, context: nil, hints: nil)
if (rectImageRef != nil) {
NSOperationQueue.mainQueue().addOperationWithBlock({
CGContextDrawImage(ctx, rect, rectImageRef)
})
}
})
答案 0 :(得分:2)
当CATiledLayer是主要层时,我们从未真正设法让它工作,我不确定它为什么不起作用,我们从来没有得到Apple提出的错误答案。
然而,我们让它通过使主层成为标准CALayer然后将CATiledLayer作为subLayer添加到这个主层来进行后台渲染,类似于下面的代码。
我们还注意到,如果在NSView中托管CATiledLayer
,它会按预期工作希望这会有所帮助......
class HostingLayer : CALayer {
var tiledLayer : CATiledLayer!
override init() {
super.init()
self.tiledLayer = CATiledLayer.init()
self.addSublayer(tiledLayer!)
}
}
答案 1 :(得分:0)
所以这就是我所做的工作,虽然它并不理想。在我drawRect:
支持CATiledLayer
的{{1}}中,我绘制了一个简单的背景(在我的例子中是一个简单的网格)。我创建了另一个NSView
,并将我的NSView层添加为子层,并将NSView设置为其委托。第二个“CATiledLayer”正在后台线程上获取委托绘制调用。