主线程检查器:UI API 在后台线程上调用:-[UIApplication applicationState]
Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
我在 Xcode 9 beta 中使用 google 地图,iOS 11.
我在日志中收到如下错误输出:
Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
PID: 4442, TID: 837820, Thread name: com.google.Maps.LabelingBehavior, Queue name: com.apple.root.default-qos.overcommit, QoS: 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)")
}
}
将修改 UI 的代码行包装在 DispatchQueue.main.async {}
中,以确保它们在主线程上执行。否则,您可能从后台线程调用它们,其中 UI 不允许修改。所有这些代码行都必须从主线程执行。
选择scheme -> Diagnotics,去掉main thread checker,警告就会消失。
scheme editor
首先,确保从主线程调用 google 映射和 ui 更改。
您可以使用以下步骤在 Xcode 中启用 Thread Sanitizer 选项:
您可以通过以下方式将有问题的行放在主线程中:
DispatchQueue.main.async {
//Do UI Code here.
//Call Google maps methods.
}
此外,更新您当前版本的 google 地图。 Google maps 必须对线程检查器进行一些更新。
对于问题:“为什么会发生这种情况?”我认为 Apple 为边缘情况添加了一个 assertion,然后 Google 必须更新他们的 pod。
参考这个link
https://developer.apple.com/documentation/code_diagnostics/main_thread_checker
对我来说,当我从块中调用时这有效。
有时很难找到不在主线程中执行的UI代码。您可以使用下面的技巧找到并修复它。
选择Edit Scheme -> Diagnostics,勾选Main Thread Checker。
Xcode 11.4.1
单击主线程检查器旁边的小箭头以创建主线程检查器断点。
上一个Xcode
勾选暂停问题。
运行 您的 iOS 应用程序可重现此问题。 (Xcode 应该在第一个问题上暂停。)
将修改UI的代码包裹在DispatchQueue.main.async {}
我想解决方案已经给出了,
我的问题是键盘在路上。
我在 Xcode 9 beta 中使用 google 地图,iOS 11.
我在日志中收到如下错误输出:
Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState] PID: 4442, TID: 837820, Thread name: com.google.Maps.LabelingBehavior, Queue name: com.apple.root.default-qos.overcommit, QoS: 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)")
}
}
将修改 UI 的代码行包装在 DispatchQueue.main.async {}
中,以确保它们在主线程上执行。否则,您可能从后台线程调用它们,其中 UI 不允许修改。所有这些代码行都必须从主线程执行。
选择scheme -> Diagnotics,去掉main thread checker,警告就会消失。 scheme editor
首先,确保从主线程调用 google 映射和 ui 更改。
您可以使用以下步骤在 Xcode 中启用 Thread Sanitizer 选项:
您可以通过以下方式将有问题的行放在主线程中:
DispatchQueue.main.async {
//Do UI Code here.
//Call Google maps methods.
}
此外,更新您当前版本的 google 地图。 Google maps 必须对线程检查器进行一些更新。
对于问题:“为什么会发生这种情况?”我认为 Apple 为边缘情况添加了一个 assertion,然后 Google 必须更新他们的 pod。
参考这个link https://developer.apple.com/documentation/code_diagnostics/main_thread_checker
对我来说,当我从块中调用时这有效。
有时很难找到不在主线程中执行的UI代码。您可以使用下面的技巧找到并修复它。
选择Edit Scheme -> Diagnostics,勾选Main Thread Checker。
Xcode 11.4.1
单击主线程检查器旁边的小箭头以创建主线程检查器断点。
上一个Xcode
勾选暂停问题。
运行 您的 iOS 应用程序可重现此问题。 (Xcode 应该在第一个问题上暂停。)
将修改UI的代码包裹在
DispatchQueue.main.async {}
我想解决方案已经给出了, 我的问题是键盘在路上。