Swift CametLayer初始化仅在主线程上工作

Swift CametLayer初始化仅在主线程上工作,swift,multithreading,metal,Swift,Multithreading,Metal,我有一个直接的CametLayer设置,除了CametLayer在全局线程上初始化,如下所示(调用init、设置基本属性和添加为子层): 此代码运行时没有任何运行时错误,但不幸的是,当渲染到CametLayerdrawable时,屏幕上没有显示渲染输出。测试表明,camertallayerdrawable确实具有适当的纹理(具有所需的大小),数据按预期写入,但未显示在屏幕上 令我惊讶的是,在主线程上运行CAMetalLayer初始化可以解决这个问题。因此,以下是一个解决方案: DispatchQ

我有一个直接的CametLayer设置,除了CametLayer在全局线程上初始化,如下所示(调用init、设置基本属性和添加为子层):

此代码运行时没有任何运行时错误,但不幸的是,当渲染到
CametLayer
drawable时,屏幕上没有显示渲染输出。测试表明,
camertallayer
drawable确实具有适当的纹理(具有所需的大小),数据按预期写入,但未显示在屏幕上

令我惊讶的是,在主线程上运行
CAMetalLayer
初始化可以解决这个问题。因此,以下是一个解决方案:

DispatchQueue.global().async {
    var renderLayer: CAMetalLayer!
    DispatchQueue.main.sync {
        renderLayer = CAMetalLayer()
    }
    renderLayer.isOpaque = false
    renderLayer.frame = frame
    renderLayer.drawableSize = drawableSize
    renderLayer.framebufferOnly = false
    renderLayer.device = metalDevice
    renderLayer.pixelFormat = metalPixelFormat
    renderLayer.contentsScale = contentScale
    DispatchQueue.main.async {
        view.layer.addSublayer(renderLayer)
    }
}
由于我希望能够在后台线程上完全运行
CAMetalLayer
创建,因此我希望避免在主线程上调用
CAMetalLayer()
。此外,我在文档中找不到在主线程上初始化
camertallayer
的任何要求

所以我的问题是:

  • 是否可以在后台线程上运行init
    CAMetalLayer()
    ,如果可以,如何运行?
  • 如果不可能:为什么?

其他信息:我正在使用XCode 11并在iOS 13.1上运行代码。我对XCode 10和iOS版本12也有同样的问题。

出色的研究!只调用主线程上的那一行有什么不好?顺便说一句,这个代码是错误的:您永远不应该调用
main.sync
。嗯,你可以,但一般来说不可以。@matt:我可以在主线程上调用这一行,但这样做感觉不对,因为我找不到需要在主线程上初始化的
camertallayer
的信息。我也很好奇是否真的有这样的要求。同时在主线程上调用一行对我来说是不方便的,因为我当前的代码需要一些调整来避免主线程上的死锁。所以如果我能避免的话,我会的。
DispatchQueue.global().async {
    var renderLayer: CAMetalLayer!
    DispatchQueue.main.sync {
        renderLayer = CAMetalLayer()
    }
    renderLayer.isOpaque = false
    renderLayer.frame = frame
    renderLayer.drawableSize = drawableSize
    renderLayer.framebufferOnly = false
    renderLayer.device = metalDevice
    renderLayer.pixelFormat = metalPixelFormat
    renderLayer.contentsScale = contentScale
    DispatchQueue.main.async {
        view.layer.addSublayer(renderLayer)
    }
}