Ios 在后台任务中将catextlayers添加到calayer

Ios 在后台任务中将catextlayers添加到calayer,ios,swift,calayer,cashapelayer,Ios,Swift,Calayer,Cashapelayer,我有一个我不明白的情况。 我喜欢在后台任务中创建CATextLayers并在视图中显示它们,因为这需要一些时间 这在没有背景任务的情况下非常有效。我可以在我的视图“worldmapview”中立即看到文本 在后台任务中执行此操作时,文本不会显示在我的视图中。有时,并非总是在几秒钟后出现(例如10秒钟) 有人看到了吗,怎么了? 非常令人困惑的是:对CAShapeLayer的相同操作也可以在后台进行。UI上的所有更改都是在主线程上执行的。无法在后台线程上更新用户界面。据 涉及视图、核心动画和许多其他

我有一个我不明白的情况。 我喜欢在后台任务中创建CATextLayers并在视图中显示它们,因为这需要一些时间

这在没有背景任务的情况下非常有效。我可以在我的视图“worldmapview”中立即看到文本

在后台任务中执行此操作时,文本不会显示在我的视图中。有时,并非总是在几秒钟后出现(例如10秒钟)

有人看到了吗,怎么了?
非常令人困惑的是:对CAShapeLayer的相同操作也可以在后台进行。

UI上的所有更改都是在主线程上执行的。无法在后台线程上更新用户界面。据

涉及视图、核心动画和许多其他UIKit类的工作 通常必须发生在应用程序的主线程上。也有一些例外 例如,根据此规则,基于图像的操作通常会发生在 背景线程,但当有疑问时,假设工作需要进行 在主线程上


UI上的所有更改都在主线程上执行。无法在后台线程上更新用户界面。据

涉及视图、核心动画和许多其他UIKit类的工作 通常必须发生在应用程序的主线程上。也有一些例外 例如,根据此规则,基于图像的操作通常会发生在 背景线程,但当有疑问时,假设工作需要进行 在主线程上


看起来
setNeedDisplay
不会导致子层重新绘制,我们需要在所有需要的层上调用它,在这种情况下,它是新添加的层

func addlayerandrefresh_background(){
    let calayer = CALayer()
    calayer.frame = self.worldmapview.bounds

    dispatch_async(backgroundQueue, {
        for var i = 0; i < 100 ; i+=10 {
            let newtextlayer:CATextLayer=self.create_text_layer(0, y1: CGFloat(i) ,width:200,heigth:200,text:"My Text ....",fontsize:5)
            calayer.addSublayer(newtextlayer)
        }
        dispatch_async(dispatch_get_main_queue(),{
            self.worldmapview.layer.addSublayer(calayer)
            for l in calayer.sublayers! {
                l.setNeedsDisplay()
            }
        })

    })
}
func addlayer和refresh_background(){
设calayer=calayer()
calayer.frame=self.worldmappview.bounds
调度异步(后台队列{
对于变量i=0;i<100;i+=10{
让newtextlayer:CATextLayer=self。创建_文本_层(0,y1:CGFloat(i),宽度:200,高度:200,文本:“我的文本…”,字体大小:5)
calayer.addSublayer(newtextlayer)
}
dispatch\u async(dispatch\u get\u main\u queue(){
self.worldmappview.layer.addSublayer(calayer)
为了我在calayer.亚层{
l、 setNeedsDisplay()
}
})
})
}

看起来像是
setNeedDisplay
不会导致子层重新绘制,我们需要在所有需要的层上调用它,在这种情况下,它是新添加的层

func addlayerandrefresh_background(){
    let calayer = CALayer()
    calayer.frame = self.worldmapview.bounds

    dispatch_async(backgroundQueue, {
        for var i = 0; i < 100 ; i+=10 {
            let newtextlayer:CATextLayer=self.create_text_layer(0, y1: CGFloat(i) ,width:200,heigth:200,text:"My Text ....",fontsize:5)
            calayer.addSublayer(newtextlayer)
        }
        dispatch_async(dispatch_get_main_queue(),{
            self.worldmapview.layer.addSublayer(calayer)
            for l in calayer.sublayers! {
                l.setNeedsDisplay()
            }
        })

    })
}
func addlayer和refresh_background(){
设calayer=calayer()
calayer.frame=self.worldmappview.bounds
调度异步(后台队列{
对于变量i=0;i<100;i+=10{
让newtextlayer:CATextLayer=self。创建_文本_层(0,y1:CGFloat(i),宽度:200,高度:200,文本:“我的文本…”,字体大小:5)
calayer.addSublayer(newtextlayer)
}
dispatch\u async(dispatch\u get\u main\u queue(){
self.worldmappview.layer.addSublayer(calayer)
为了我在calayer.亚层{
l、 setNeedsDisplay()
}
})
})
}

请查看我的答案。我认为这个问题不需要悬赏。很简单:)嗨,法瓦德。对你来说可能很简单:-),但我还是不知道怎么做。你能帮我更多吗?我的代码只需粘贴即可重现问题。我将很高兴看到这项工作得到纠正。因为从理论和阅读文档来看,我还是不明白。你说“这在没有背景任务的情况下工作很完美”,那你为什么要在背景中做呢?我已经在主线程上执行了任务(使用您的代码),我正在worldMapView上添加100个子视图,没有延迟。请检查是否有其他原因导致延迟。请查看我的答案。我认为这个问题不需要悬赏。很简单:)嗨,法瓦德。对你来说可能很简单:-),但我还是不知道怎么做。你能帮我更多吗?我的代码只需粘贴即可重现问题。我将很高兴看到这项工作得到纠正。因为从理论和阅读文档来看,我还是不明白。你说“这在没有背景任务的情况下工作很完美”,那你为什么要在背景中做呢?我已经在主线程上执行了任务(使用您的代码),我正在worldMapView上添加100个子视图,没有延迟。请检查是否有其他原因导致延迟。您能否解释一下
performSelectorOnMainThread:
dispatch\u async(dispatch\u get\u main\u queue()…
@sage444抱歉,由于CALayer是一个核心动画类,您无法在后台线程上对其执行更改。我已更新了答案:)很抱歉我不明白。我想我正在更新主线程中的GUI。但是你的代码片段很有意思,它显然已经消失了。我尝试过,但AppDelegate类出错。“libc++abi.dylib:以NSException类型的未捕获异常终止”。你的答案中的代码到哪里去了?我意识到我发布的代码不起作用。所以我把它拿走了。简单的回答是,您不能在主线程上更新核心动画和UIKit类。如果你想要这个代码片段,我可以再发一次。我真的很高兴看到这个代码片段。您可以简单地对我的代码进行测试。您将不得不重现backgroundtask案例的问题。您能解释一下
performSelectorOnMainThread:
dispatch\u async(dispatch\u get\u main\u queue()之间的区别吗…
@sage444抱歉,由于CALayer是一个核心动画类,您无法在后台线程上对其执行更改。我已更新了答案:)我必须为我不理解而道歉。我想我正在更新主线程中的GUI。但是你的代码片段很有意思,它显然已经消失了。我尝试过,但AppDelegate类出错。“libc++abi.dylib:以NSException类型的未捕获异常终止”。你的答案中的代码到哪里去了?我意识到我发布的代码不起作用。所以我把它拿走了。
func addlayerandrefresh_background(){
    let calayer = CALayer()
    calayer.frame = self.worldmapview.bounds

    dispatch_async(backgroundQueue, {
        for var i = 0; i < 100 ; i+=10 {
            let newtextlayer:CATextLayer=self.create_text_layer(0, y1: CGFloat(i) ,width:200,heigth:200,text:"My Text ....",fontsize:5)
            calayer.addSublayer(newtextlayer)
        }
        dispatch_async(dispatch_get_main_queue(),{
            self.worldmapview.layer.addSublayer(calayer)
            for l in calayer.sublayers! {
                l.setNeedsDisplay()
            }
        })

    })
}