ios - 使用 dispatch_async() 避免 View 阻塞的解决方法是什么

标签 ios multithreading swift

我有这个 View ,带有几个标签和一张 map 。 在这个 View 中,我显示了一些关于地理位置点的信息:

  • 地址
  • map + 图钉
  • 第一个标签(已计算)
  • 第二个标签(已计算)

加载 View 后,我需要进行一些计算以更新标签。 这个计算需要几秒钟(我需要调用一个 API)所以我把它们放在一个队列中:

dispatch_async(dispatch_get_main_queue(), {
    let loc = CLLocationCoordinate2D(latitude: self.place!.location.latitude, longitude: self.place!.location.longitude)
    let tmp = Int(Geo.apiCall(self.currentPosition, coordTo: loc));
    self.label1.text = " = \(tmp) unit";
})

我使用了主线程 dispatch_get_main_queue() 因为我需要更新标签。 问题在于它阻止了 map 的呈现,并且还阻止了 CLGeocoder 的另一个异步函数,该函数正在从地理位置点收集地址。

let loc = CLLocation(latitude: self.place!.location.latitude, longitude: self.place!.location.longitude)

CLGeocoder().reverseGeocodeLocation(loc, completionHandler:
    {(placemarks, error) in
        if error != nil {
            println("reverse geodcode fail: \(error.localizedDescription)")
        }
        let pms = placemarks as [CLPlacemark]
        if pms.count > 0 {
            let pm = placemarks[0] as CLPlacemark
            self.address.text = ABCreateStringWithAddressDictionary(pm.addressDictionary, false)
        }
})

因此 View 显示正确,但所有标签同时更新, View 显示几秒后, map 仅在标签呈现时加载。

在渲染 View 时避免这种阻塞的最佳解决方法是什么?

最佳答案

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT) {
    //Background Thread
    let loc = CLLocationCoordinate2D(latitude: self.place!.location.latitude,         longitude: self.place!.location.longitude)
    let tmp = Int(Geo.apiCall(self.currentPosition, coordTo: loc));

    dispatch_async(dispatch_get_main_queue()) {
        //Run UI Updates
        self.label1.text = " = \(tmp) unit";
    }
}

获取一个后台线程来完成不直接涉及更改ui的工作,然后在需要时调用主队列。归功于:Understanding dispatch_async

编辑:另一种选择是使用 AFNetworking(用于 objective-c)Alamofire(用于 swift),它将异步调用您的 api,并且您可以更改完成处理程序中的标签:https://github.com/AFNetworking/AFNetworking ,教程:http://www.raywenderlich.com/59255/afnetworking-2-0-tutorial

EDIT-2:我没有注意并将 objective-c 调用与您的快速声明混合在一起:P

关于ios - 使用 dispatch_async() 避免 View 阻塞的解决方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26579943/

相关文章:

ios - 如何防止我的表格的单元格滚动到我的表格框架之外

C++ 如果一个线程写入后切换一个 bool 值,那么在另一个线程的循环中读取该 bool 值是否安全?

Swift - 核心数据。枚举时集合发生变异

ios - ?? Swift 中的运算符

ios - 在 Swift 2 项目中使用 Swift 3 库

ios - ios 中的 SWRevealViewController 给出桥接 header 错误

ios:短格式日期选择器

multithreading - 在连接开始时将 SSL 与 Netty 结合使用,然后将其禁用

ios - Swift WHOLE_MODULE_OPTIMIZATION 改进了编译时间,但导致 lldb/Xcode 崩溃

ios - SwiftHTTP 认证错误超时