2016-09-19 70 views
7

我正在使用CATiledLayer支持的NSView(Mac不是iOS),并且根据Apple文档https://developer.apple.com/reference/quartzcore/catiledlayer我期望在多线程上可以异步调用它以提高性能,但它似乎只能在主线程中调用。CATiledLayer drawLayer:inContext始终在主线程上调用 - MacOS El Capitan

我做我已经在一个NSView启用canDrawConcurrentlydrawLayer(layer: CALayer, inContext ctx: CGContext)

工作以及确保窗口allowsConcurrentViewDrawing设置为true(默认),但它仍然总是用于每个图块的主线程调用上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

你有没有想出解决办法?我看到了同样的事情。我想使用后台线程绘制到我的NSView的CATiledLayer。 –

+0

这里有更多的上下文。如果我将另一个CATiledLayer作为叠加层添加到作为我的后备叠加层的叠加层中,它将在后台呈现。只是主视图在主线程上呈现的主体。我最终可能会将主要部分变成空白,并将渲染放到覆盖层CATiledLayer中。 –

回答

0

所以这是我做了工作,但它并不理想。在drawRect:为我的CATiledLayer支持NSView我画了一个简单的背景(在我的情况下一个简单的网格)。我创建了另一个CATiledLayer,并将其作为子图层添加到NSView的图层中,并将NSView设置为其委托。这第二个`CATiledLayer'正在后台线程上获取委托绘制调用。

1

当CATiledLayer是主图层时,我们从未真正设法让它工作,我不确定它为什么不起作用,我们从来没有从提出的Apple bug中得到答案。

但是,我们通过将主图层制作为标准CALayer,然后将CATiledLayer作为子图层添加到此主图层来实现背景渲染,类似于以下代码。

我们也注意到了这一点和预期一样,如果在一个NSView

希望这有助于托管CATiledLayer ...

class HostingLayer : CALayer { 

    var tiledLayer : CATiledLayer! 

    override init() { 
     super.init() 

     self.tiledLayer = CATiledLayer.init() 

     self.addSublayer(tiledLayer!) 
    } 
}