124

我在 Xcode 9 beta、iOS 11 中使用谷歌地图。

我收到一个错误输出到日志,如下所示:

主线程检查器:在后台线程上调用的 UI API:-[UIApplication applicationState] PID:4442,TID:837820,线程名称:com.google.Maps.LabelingBehavior,队列名称:com.apple.root.default-qos.overcommit , 服务质量: 21

为什么会发生这种情况,因为我几乎可以肯定我没有更改代码中主线程的任何界面元素。

 override func viewDidLoad() {

    let locationManager = CLLocationManager()


    locationManager.requestAlwaysAuthorization()


    locationManager.requestWhenInUseAuthorization()

        if CLLocationManager.locationServicesEnabled() {

            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()
        }

      viewMap.delegate = self

     let camera = GMSCameraPosition.camera(withLatitude: 53.7931183329367, longitude: -1.53649874031544, zoom: 17.0)


        viewMap.animate(to: camera)


    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let locValue:CLLocationCoordinate2D = manager.location!.coordinate
        print("locations = \(locValue.latitude) \(locValue.longitude)")
    }

    func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {


    }

    func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {

        if(moving > 1){
            moving = 1
        UIView.animate(withDuration: 0.5, delay: 0, animations: {

            self.topBarConstraint.constant = self.topBarConstraint.constant + (self.topBar.bounds.height / 2)

            self.bottomHalfConstraint.constant = self.bottomHalfConstraint.constant + (self.topBar.bounds.height / 2)

            self.view.layoutIfNeeded()
        }, completion: nil)
    }
         moving = 1
    }


    // Camera change Position this methods will call every time
    func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
        moving = moving + 1
        if(moving == 2){


            UIView.animate(withDuration: 0.5, delay: 0, animations: {


                self.topBarConstraint.constant = self.topBarConstraint.constant - (self.topBar.bounds.height / 2)

                self.bottomHalfConstraint.constant = self.bottomHalfConstraint.constant - (self.topBar.bounds.height / 2)


                self.view.layoutIfNeeded()
            }, completion: nil)
        }
        DispatchQueue.main.async {

            print("Moving: \(moving) Latitude: \(self.viewMap.camera.target.latitude)")
            print("Moving: \(moving)  Longitude: \(self.viewMap.camera.target.longitude)")
        }
    }
4

6 回答 6

171

有时很难找到不在主线程中执行的 UI 代码。您可以使用下面的技巧找到并修复它。

  1. 选择 Edit Scheme -> Diagnostics,勾选 Main Thread Checker。

    Xcode 11.4.1

    单击主线程检查器旁边的小箭头以创建主线程检查器断点。 在此处输入图像描述

    以前的 Xcode

    勾选暂停问题。 在此处输入图像描述

  2. 运行您的 iOS 应用程序以重现此问题。(Xcode 应该在第一个问题上暂停。) 在此处输入图像描述

  3. 将修改 UI 的代码包装在DispatchQueue.main.async {} 在此处输入图像描述

于 2018-04-25T09:44:46.180 回答
80

首先,确保从主线程调用 google maps 和 ui 更改。

您可以使用以下步骤在 Xcode 中启用Thread Sanitizer选项:

截屏

您可以使用以下内容在主线程上放置违规行:

DispatchQueue.main.async {
    //Do UI Code here. 
    //Call Google maps methods.
}

此外,更新您当前版本的谷歌地图。谷歌地图必须对线程检查器进行一些更新。

对于这个问题:“为什么会发生这种情况?” 我认为苹果为边缘案例添加了一个断言,然后谷歌不得不更新他们的 pod。

于 2017-08-28T07:09:21.170 回答
51

包装修改 UI 的代码行,DispatchQueue.main.async {}以确保它们在主线程上执行。否则,您可能会从不允许修改 UI 的后台线程调用它们。所有这些代码行都必须从主线程执行。

于 2017-07-05T16:23:27.043 回答
4

请参阅此链接 https://developer.apple.com/documentation/code_diagnostics/main_thread_checker

对我来说,当我从块中调用时,这很有效。

于 2017-11-28T03:14:53.157 回答
0

我认为解决方案已经给出,因为我的问题是键盘在路上。

UIKeyboardTaskQueue 只能从主线程调用

于 2019-06-14T05:35:59.193 回答
-40

选择方案 -> 诊断,删除主线程检查器,然后警告将消失。 方案编辑

于 2017-08-22T08:47:14.627 回答