如何解决移动到后台时,使用 CoreLocation 会使我的应用程序崩溃
我在这里有一个非常简单的 iOS 应用程序(Swift 5 和 XCode 12.3)。它只有两个按钮来启动和停止 CLLocationManager。当应用程序在前台时,一切似乎都运行良好。问题是即使应用程序不在前台,我也想继续接收更新。我激活了“背景模式”、“位置更新”的复选标记。但它不起作用。一旦我将应用程序置于后台(从我的 iPhone XR 底部向上滑动),它就会崩溃并显示以下错误:
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: mutex lock Failed: Invalid argument
terminating with uncaught exception of type std::__1::system_error: mutex lock Failed: Invalid argument
我还在 Info.plist 中提供了“隐私 - 位置始终和使用时使用说明”和“隐私 - 使用时位置使用说明”的键。我的视图控制器的代码如下:
import UIKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate {
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.showsBackgroundLocationIndicator = true
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.activityType = .other
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = kCLdistanceFilterNone
}
@IBAction func play(_ sender: UIButton) {
locationManager.requestAlwaysAuthorization()
self.locationManager.startUpdatingLocation()
}
@IBAction func stop(_ sender: UIButton) {
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager,didUpdateLocations locations: [CLLocation]) {
locations.forEach { (location) in
print(location)
}
print("\n")
}
}
堆栈跟踪看起来像并报告了 SIGABRT:
libsystem_kernel.dylib`__pthread_kill:
0x1c153240c <+0>: mov x16,#0x148
0x1c1532410 <+4>: svc #0x80
-> 0x1c1532414 <+8>: b.lo 0x1c1532434 ; <+40>
0x1c1532418 <+12>: pacibsp
0x1c153241c <+16>: stp x29,x30,[sp,#-0x10]!
0x1c1532420 <+20>: mov x29,sp
0x1c1532424 <+24>: bl 0x1c150ec20 ; cerror_nocancel
0x1c1532428 <+28>: mov sp,x29
0x1c153242c <+32>: ldp x29,[sp],#0x10
0x1c1532430 <+36>: retab
0x1c1532434 <+40>: ret
有时它也会因 EXC_BAD_ACCESS 和以下冗长的堆栈跟踪而崩溃:
libobjc.A.dylib`objc_msgSend:
0x1a85f40e0 <+0>: cmp x0,#0x0 ; =0x0
0x1a85f40e4 <+4>: b.le 0x1a85f41a4 ; <+196>
0x1a85f40e8 <+8>: ldr x13,[x0]
0x1a85f40ec <+12>: and x16,x13,#0x7ffffffffffff8
0x1a85f40f0 <+16>: xpacd x16
0x1a85f40f4 <+20>: mov x15,x16
-> 0x1a85f40f8 <+24>: ldr x11,[x16,#0x10]
0x1a85f40fc <+28>: tbnz w11,#0x0,0x1a85f4158 ; <+120>
0x1a85f4100 <+32>: and x10,x11,#0xffffffffffff
0x1a85f4104 <+36>: eor x12,x1,lsr #7
0x1a85f4108 <+40>: and x12,x12,lsr #48
0x1a85f410c <+44>: add x13,x10,lsl #4
0x1a85f4110 <+48>: ldp x17,x9,[x13],#-0x10
0x1a85f4114 <+52>: cmp x9,x1
0x1a85f4118 <+56>: b.ne 0x1a85f4128 ; <+72>
0x1a85f411c <+60>: eor x10,x1
0x1a85f4120 <+64>: eor x10,x16
0x1a85f4124 <+68>: brab x17,x10
0x1a85f4128 <+72>: cbz x9,0x1a85f44e0 ; _objc_msgSend_uncached
0x1a85f412c <+76>: cmp x13,x10
0x1a85f4130 <+80>: b.hs 0x1a85f4110 ; <+48>
0x1a85f4134 <+84>: add x13,lsr #44
0x1a85f4138 <+88>: add x12,lsl #4
0x1a85f413c <+92>: ldp x17,#-0x10
0x1a85f4140 <+96>: cmp x9,x1
0x1a85f4144 <+100>: b.eq 0x1a85f411c ; <+60>
0x1a85f4148 <+104>: cmp x9,#0x0 ; =0x0
0x1a85f414c <+108>: ccmp x13,ne
0x1a85f4150 <+112>: b.hi 0x1a85f413c ; <+92>
0x1a85f4154 <+116>: b 0x1a85f44e0 ; _objc_msgSend_uncached
0x1a85f4158 <+120>: and x10,#0x7ffffffffffffe
0x1a85f415c <+124>: autdb x10,x16
0x1a85f4160 <+128>: adrp x9,235816
0x1a85f4164 <+132>: add x9,#0x4fa ; =0x4fa
0x1a85f4168 <+136>: sub x12,x9
0x1a85f416c <+140>: lsr x17,#55
0x1a85f4170 <+144>: lsr w9,w12,w17
0x1a85f4174 <+148>: lsr x17,#60
0x1a85f4178 <+152>: mov x11,#0x7fff
0x1a85f417c <+156>: lsr x11,x17
0x1a85f4180 <+160>: and x9,x11
0x1a85f4184 <+164>: ldr x17,[x10,lsl #3]
0x1a85f4188 <+168>: cmp x12,w17,uxtw
0x1a85f418c <+172>: b.ne 0x1a85f4198 ; <+184>
0x1a85f4190 <+176>: sub x17,x16,x17,lsr #32
0x1a85f4194 <+180>: br x17
0x1a85f4198 <+184>: ldursw x9,#-0x8]
0x1a85f419c <+188>: add x16,x9
0x1a85f41a0 <+192>: b 0x1a85f40f8 ; <+24>
0x1a85f41a4 <+196>: b.eq 0x1a85f41c8 ; <+232>
0x1a85f41a8 <+200>: and x10,x0,#0x7
0x1a85f41ac <+204>: asr x11,#55
0x1a85f41b0 <+208>: cmp x10,#0x7 ; =0x7
0x1a85f41b4 <+212>: csel x12,eq
0x1a85f41b8 <+216>: adrp x10,319023
0x1a85f41bc <+220>: add x10,#0x820 ; =0x820
0x1a85f41c0 <+224>: ldr x16,lsl #3]
0x1a85f41c4 <+228>: b 0x1a85f40f4 ; <+20>
0x1a85f41c8 <+232>: mov x1,#0x0
0x1a85f41cc <+236>: movi d0,#0000000000000000
0x1a85f41d0 <+240>: movi d1,#0000000000000000
0x1a85f41d4 <+244>: movi d2,#0000000000000000
0x1a85f41d8 <+248>: movi d3,#0000000000000000
0x1a85f41dc <+252>: ret
我不知道这些痕迹是什么意思,也没有在网上找到结论性的解释。有人能给我提供一些见解吗(或者真的只是在后台运行 CLLocationManager 的最基本示例?谢谢。
解决方法
好的。经过一些额外的实验,我发现了这个问题。一切实际上都像宣传的那样工作。但是,在物理设备上测试后台模式时,永远不要在函数中使用 print
调用。只要使用模拟器,我上面发布的示例就可以工作。但是 print
语句在真实设备上确实会崩溃。我猜,原因是真机没有连接终端。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。