等待方法执行,直到在Swift中满足条件为止

问题描述 投票:0回答:1

我有一个MKMapView,带有一些注释,这些注释由代表用户共享其位置的代码添加。我通过websocket获得有关位置更改的更新,并更新了表示MKAnnotation中注释的相应coordinateMKMapView

这通常效果很好,我看到用户在地图上移动。问题在于,当用户平移或缩放地图时更新MKAnnotation.cooridnate时,MKMapView崩溃,表示哈希表在评估时已更新。基本上是这个问题:MKMapView crashing if zooming while adding annotations

[推荐的解决方案是不对MKAnnotation.cooridnateMKMapView之间的regionWillChangeAnimated进行任何操作(例如更新我的情况下的regionDidChangeAnimated,我正在尝试实现这一点。

问题是我的数据是通过websocket接收的,所以我不能只是“停止”监听这2个委托方法之间的新数据。从理论上讲我可以,但是那将意味着丢失一些数据,这不是解决方案。

我的想法是,我需要某种队列,将其用于将更新添加到MKAnnotation.cooridnate,并且将在regionWillChangeAnimated中暂停并在regionDidChangeAnimated中恢复。

我尝试以上述方式使用DispatchQueue,但过一会儿它会锁定。我不确定是否是因为对其添加了大量操作或对suspendresume的调用。如果未锁定,则过一会儿就会使应用程序崩溃。

我的问题是什么机制在这里起作用?

如问题标题中所述,我基本上需要一种使某些方法等待条件的方法,比如说在regionWillChangeAnimatedregionDidChangeAnimated之间切换可靠且可以承担负载的标志。

ios swift concurrency mapkit
1个回答
0
投票

一种方法是将这些调度到一个队列,该队列的目标是主队列:

let annotationChangeQueue = DispatchQueue(label: "...", target: .main)

通过使用主队列的目标,这意味着您可以使用此队列进行与UI相关的更改。但这也意味着您可以在区域更改正在进行时挂起该队列(不影响主队列):

func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
    annotationChangeQueue.suspend()
}

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    annotationChangeQueue.resume()
}

[顺便说一句,在上面的评论中建议suspendresume不起作用,因为它不会暂停正在进行的任何操作。但是因为我们使用.main作为目标,所以绝不会与主线程上的任何内容同时发生,因此在这种情况下这不是问题。

© www.soinside.com 2019 - 2024. All rights reserved.