CoreMotion 的主线程检查器警告,仅出现在 2018 款 iPhone 上
Main Thread Checker warning with CoreMotion, only appearing on 2018 model iPhones
以下是问题的极其简化版本:
import UIKit
import CoreMotion
class ViewController: UIViewController {
private let manager = CMMotionManager()
private let interval = 0.01
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
startUpdates()
}
private func startUpdates() {
let queue = OperationQueue()
queue.name = "com.demo.motion"
queue.qualityOfService = .userInteractive
queue.maxConcurrentOperationCount = 1
manager.accelerometerUpdateInterval = interval
manager.startAccelerometerUpdates(to: queue) { _, _ in }
}
}
当我在 iPhone XR 上 运行 时,我将收到以下信息:
Main Thread Checker: UI API called on a background thread:
-[UIApplication applicationState] PID: 1237, TID: 147763, Thread name: com.apple.CoreMotion.MotionThread, Queue name:
com.apple.root.default-qos.overcommit, QoS: 0
- 我的设备是 运行ning 12.3,这是目前最新的 iOS 版本
- 运行 在各种 iPad(2018 之前)、iPhone 8、iPhone 6S 和其他旧型号上,不会出现此问题。
- 更改
qualityOfService
对此没有影响(我的偏好是使用utility
)
- 出于好奇,我将整个
startUpdates()
函数包裹在主调度中,但没有成功
根据队列名称和发生这种情况时,我的假设是这是内部的东西,与旧设备相比,XR 中更快的处理器刚刚暴露出来。
使用 iOS 13
时的新答案
我刚刚在 2018 设备上使用新发布的 iOS 13 版本 (17A577) 对此进行了测试,它不再产生线程错误。
使用 iOS 12
时的先前答案
这是一个已知问题,已报告给 Apple with a radar linked here。
以下是问题的极其简化版本:
import UIKit
import CoreMotion
class ViewController: UIViewController {
private let manager = CMMotionManager()
private let interval = 0.01
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
startUpdates()
}
private func startUpdates() {
let queue = OperationQueue()
queue.name = "com.demo.motion"
queue.qualityOfService = .userInteractive
queue.maxConcurrentOperationCount = 1
manager.accelerometerUpdateInterval = interval
manager.startAccelerometerUpdates(to: queue) { _, _ in }
}
}
当我在 iPhone XR 上 运行 时,我将收到以下信息:
Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState] PID: 1237, TID: 147763, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos.overcommit, QoS: 0
- 我的设备是 运行ning 12.3,这是目前最新的 iOS 版本
- 运行 在各种 iPad(2018 之前)、iPhone 8、iPhone 6S 和其他旧型号上,不会出现此问题。
- 更改
qualityOfService
对此没有影响(我的偏好是使用utility
) - 出于好奇,我将整个
startUpdates()
函数包裹在主调度中,但没有成功
根据队列名称和发生这种情况时,我的假设是这是内部的东西,与旧设备相比,XR 中更快的处理器刚刚暴露出来。
使用 iOS 13
时的新答案我刚刚在 2018 设备上使用新发布的 iOS 13 版本 (17A577) 对此进行了测试,它不再产生线程错误。