ios - 移动到后台时,使用 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, x30, [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, x1, lsr #7
0x1a85f4108 <+40>: and x12, x12, x11, lsr #48
0x1a85f410c <+44>: add x13, x10, x12, lsl #4
0x1a85f4110 <+48>: ldp x17, x9, [x13], #-0x10
0x1a85f4114 <+52>: cmp x9, x1
0x1a85f4118 <+56>: b.ne 0x1a85f4128 ; <+72>
0x1a85f411c <+60>: eor x10, x10, x1
0x1a85f4120 <+64>: eor x10, 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, x10, x11, lsr #44
0x1a85f4138 <+88>: add x12, x10, x12, lsl #4
0x1a85f413c <+92>: ldp x17, x9, [x13], #-0x10
0x1a85f4140 <+96>: cmp x9, x1
0x1a85f4144 <+100>: b.eq 0x1a85f411c ; <+60>
0x1a85f4148 <+104>: cmp x9, #0x0 ; =0x0
0x1a85f414c <+108>: ccmp x13, x12, #0x0, ne
0x1a85f4150 <+112>: b.hi 0x1a85f413c ; <+92>
0x1a85f4154 <+116>: b 0x1a85f44e0 ; _objc_msgSend_uncached
0x1a85f4158 <+120>: and x10, x11, #0x7ffffffffffffe
0x1a85f415c <+124>: autdb x10, x16
0x1a85f4160 <+128>: adrp x9, 235816
0x1a85f4164 <+132>: add x9, x9, #0x4fa ; =0x4fa
0x1a85f4168 <+136>: sub x12, x1, x9
0x1a85f416c <+140>: lsr x17, x11, #55
0x1a85f4170 <+144>: lsr w9, w12, w17
0x1a85f4174 <+148>: lsr x17, x11, #60
0x1a85f4178 <+152>: mov x11, #0x7fff
0x1a85f417c <+156>: lsr x11, x11, x17
0x1a85f4180 <+160>: and x9, x9, x11
0x1a85f4184 <+164>: ldr x17, [x10, x9, 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, [x10, #-0x8]
0x1a85f419c <+188>: add x16, x16, x9
0x1a85f41a0 <+192>: b 0x1a85f40f8 ; <+24>
0x1a85f41a4 <+196>: b.eq 0x1a85f41c8 ; <+232>
0x1a85f41a8 <+200>: and x10, x0, #0x7
0x1a85f41ac <+204>: asr x11, x0, #55
0x1a85f41b0 <+208>: cmp x10, #0x7 ; =0x7
0x1a85f41b4 <+212>: csel x12, x11, x10, eq
0x1a85f41b8 <+216>: adrp x10, 319023
0x1a85f41bc <+220>: add x10, x10, #0x820 ; =0x820
0x1a85f41c0 <+224>: ldr x16, [x10, x12, 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
语句在真实设备上确实会崩溃。我想,原因是真实设备没有连接终端。
推荐阅读
- php - 更新 JSON 对象 PHP
- powerbi - 如何集成本地 Power BI 和 PowerPoint
- java - 如何在 IntelliJ IDEA 控制台输出中隐藏命令行?
- r - 我可以按字母顺序使用字母来表示重复的列而不是 R 中的数字吗?
- ruby - 不使用 Enumerable 类或哈希或映射的 Ruby 置换方法代码
- c# - HttpPost 在 ASP.NET MVC 中返回空模型
- angularjs - 错误:[$injector:unpr] 未知提供者:rProvider <- r <- notificationsBarDirective
- python - SQLAlchemy (sqlite3.OperationalError) 没有这样的表:
- python - 如何仅暂停 IF 语句,而不是整个代码 Python
- apache-kafka - Kafka 拓扑设计:如何在超时时加入滑动窗口并发出事件?[难的]