Closed hiroshi-shin closed 3 years ago
I could not figure out exactly what was happening with the provided information. I need your complete code (or minimum set of codes) to reproduce the issue on my device.
For the first launch, when I open the map from my customized UINavigationController in Swift, it had no problem. However, the second time when I did the same thing, the app crashed.
Is this a hot start problem?
For the approach 2, it would not crash for the second launch, but this would cost extra resource when the map is not showing.
If you call both the start and the stop of HLPLocationManager in a short period of time, it could cause problems.
Thread 6 name: Dispatch queue: NSOperationQueue 0x107e044c0 (QOS: USER_INTERACTIVE)
Thread 6 Crashed:
0 libsystem_kernel.dylib 0x00000001bb3b3334 __pthread_kill + 8
1 libsystem_pthread.dylib 0x00000001d8dfda9c pthread_kill + 272
2 libsystem_c.dylib 0x0000000196530b90 abort + 104
3 libc++abi.dylib 0x00000001a1d2abb8 __cxxabiv1::__aligned_malloc_with_fallback+ 80824 (unsigned long) + 0
4 libc++abi.dylib 0x00000001a1d1bec8 demangling_unexpected_handler+ 20168 () + 0
5 libobjc.A.dylib 0x00000001a1c2806c _objc_terminate+ 28780 () + 160
6 libc++abi.dylib 0x00000001a1d29fa0 std::__terminate(void (*)+ 77728 ()) + 20
7 libc++abi.dylib 0x00000001a1d29f2c std::terminate+ 77612 () + 48
8 libdispatch.dylib 0x000000018cd6f830 _dispatch_client_callout + 40
9 libdispatch.dylib 0x000000018cd72cf4 _dispatch_continuation_pop + 448
10 libdispatch.dylib 0x000000018cd72384 _dispatch_async_redirect_invoke + 592
11 libdispatch.dylib 0x000000018cd80fe0 _dispatch_root_queue_drain + 388
12 libdispatch.dylib 0x000000018cd817d8 _dispatch_worker_thread2 + 112
13 libsystem_pthread.dylib 0x00000001d8dfe768 _pthread_wqthread + 216
14 libsystem_pthread.dylib 0x00000001d8e0574c start_wqthread + 8
Unfortunately, the stack trace does not provide a clear clue to figure out the issue. However, I guess it could happen if you free (stop) resources while starting the manager.
In order to explain the situation, I've created a sample view like this:
class TestController: UIViewController {
private let btn = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
btn.setTitle("Segue", for: .normal)
btn.setTitleColor(.blue, for: .normal)
btn.sizeToFit()
btn.addTarget(self, action: #selector(openMap), for: .touchUpInside)
self.view.addSubview(btn)
self.view.backgroundColor = .white
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
btn.center = self.view.center
}
@objc private func openMap() {
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "blind_ui")
self.showDetailViewController(vc, sender: self)
}
override func viewWillDisappear(_ animated: Bool) {
guard let manager = HLPLocationManager.shared() else { return }
let modalName = UserDefaults.standard.string(forKey: "bleloc_map_data")
let docPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
if let name = modalName,
let path = docPath {
manager.setModelPath(path.appendingPathComponent(name).absoluteString)
let params = InitViewController.getLocationManagerParams()
manager.parameters = params
manager.start()
}
}
}
In order to stop TTS and any other navigation functions, I added this viewWillDisappear
to BlindViewController
:
- (void)viewWillDisappear:(BOOL)animated {
_webView.delegate = nil;
[navigator stop];
navigator.delegate = nil;
navigator = nil;
commander.delegate = nil;
commander = nil;
previewer.delegate = nil;
previewer = nil;
dialogHelper.delegate = nil;
dialogHelper = nil;
_settingButton = nil;
[[NSUserDefaults standardUserDefaults] removeObserver:self forKeyPath:@"developer_mode"];
}
If you call both the start and the stop of HLPLocationManager in a short period of time, it could cause problems. However, I guess it could happen if you free (stop) resources while starting the manager.
I think that I accidentally called stop
somewhere.
Moreover, as you suggested, I will consider not to call the start
function every time when opening the map, because the app is originally designed to load the map only once.
I found the issue in setting the model path.
The path needs to be like /var/mobile/Containers/Data/...
,
but with your code, the path is like file:///var/mobile/Containers/Data/...
So, please fix the path by changing the code like the following.
guard let manager = HLPLocationManager.shared() else { return }
let modalName = UserDefaults.standard.string(forKey: "bleloc_map_data")
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
if let name = modalName {
manager.setModelPath(path.appendingPathComponent(name))
let params = InitViewController.getLocationManagerParams()
manager.parameters = params
manager.start()
}
Situation
For the first launch, when I open the map from my customized UINavigationController in Swift, it had no problem.
However, the second time when I did the same thing, the app crashed.
Here is the crash log:
I started the HLPLocationManager inside the my customized UIViewController's prepareForSegue function:
The customized UIViewController is displayed at the end of WelcomeViewController#checkConfig
and ended it when BlindViewController is closed:
What I tried
manager.start()
For the approach 2, it would not crash for the second launch, but this would cost extra resource when the map is not showing.