如何解决在调用stopDeviceMotionUpdates之后引发iOS CoreMotion.MotionThread EXC_BAD_ACCESS
我有一个使用CoreMotion监视设备姿态的视图控制器。
以下是在调用startDeviceMotionUpdates()时使用的处理程序:
/**
* Receives device motion updates from Core Motion and uses the attitude of the device to update
* the position of the attitude tracker inside the bubble level view.
*/
private func handleAttitude(deviceMotion: CMDeviceMotion?,error: Error?) {
guard let attitude = deviceMotion?.attitude else {
GLog.Error(message: "Could not get device attitude.")
return
}
// Calculate the current attitude vector
let roll = attitude.roll
let pitch = attitude.pitch - optimalAngle
let magnitude = sqrt(roll * roll + pitch * pitch)
// Drawing can only happen on the main thread
DispatchQueue.main.async {
[weak self] in
guard let weakSelf = self else {
GLog.Log("could not get weak self")
return
}
// Move the bubble in the attitude tracker to match the current attitude
weakSelf.bubblePosX.constant = CGFloat(roll * weakSelf.attitudeScalar)
weakSelf.bubblePosY.constant = CGFloat(pitch * weakSelf.attitudeScalar)
// Set the border color based on the current attitude.
if magnitude < weakSelf.yellowThreshold {
weakSelf.attitudeView.layer.borderColor = weakSelf.green.cgColor
} else if magnitude < weakSelf.redThreshold {
weakSelf.attitudeView.layer.borderColor = weakSelf.yellow.cgColor
} else {
weakSelf.attitudeView.layer.borderColor = weakSelf.red.cgColor
}
// Do the actual drawing
weakSelf.view.layoutIfNeeded()
}
}
我添加了[弱自我],以查看它是否可以解决问题,但不能解决问题。此崩溃不容易重现。
当我完成使用CoreMotion的VC时,我在VC的viewWillDisappear()方法中调用stopDeviceMotionUpdates()。该VC是应用程序中唯一导入CoreMotion的类。
但是,当我到达下一个VC时,偶尔会看到EXC_BAD_ACCESS被抛出到了一个co.apple.CoreMotion.MotionThread。
有人知道为什么CoreMotion在使用了它的VC被关闭后会生成一个线程吗?我已验证崩溃发生时VC不再在内存中。是的,我正在处理的两个VC是模态呈现的。
我已经检查了内存图,当崩溃发生时,正在报告这些CoreMotion对象:
并且:
我不知道在释放了CoreMotionManager实例之后,那些对象是否仍然应该在内存中。根据内存图,内存中没有CoreMotionManager的实例。
导入CoreMotion的VC也导入ARKit。不确定CoreMotion和ARKit之间是否存在某种疯狂的交互作用。
主线程和MotionThread(14)之间似乎确实发生了某些事情:
我不确定要如何处理主线程堆栈跟踪。
有时候,关闭CoreMotion VC时,我注意到它释放所使用的内存存在滞后。释放总是最终发生。
感谢任何可以提供帮助的人!
解决方法
您是否将函数handleAttitude
传递给startDeviceMotionUpdates
如startDeviceMotionUpdates(to:someQueue,withHandler:handleAttitude)
这将在VC和CMMotionManager
之间建立保留周期
尝试
singletonMM.startDeviceMotionUpdates(to:someQueue) { [weak self] motion,error in
self?.handleAttitude(motion,error)
}
为避免强烈引用您的VC。
,我们有一个ARSCNView成员。当我们解散使用sceneView成员的VC时,我们没有调用sceneView.session.pause()。一行代码。就是这样。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。