iOS 9.3调用openURL后冻结
iOS 9.3 freeze after calling openURL
我的应用程序在 iOS 9.3 build 13E233 和 13E234 上调用 openURL
后冻结。
我尝试使用 dispatch_after
,但这并不能解决问题。
这是代码,没什么特别的。
+ (void)someMethod:(UIView *)senderView {
[Utility showLoadingHUDWithText:nil inView:senderView];
[[SomeClient sharedClient] someNetworkAPI:^(id result) {
[Utility hideAllHUDsForView:senderView];
NSDictionary *dict = (NSDictionary *)result;
NSString *someString = dict[@"someKey"];
NSURL *url = [NSURL URLWithString:someString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
} fail:^(NSError *error) {
[Utility hideAllHUDsForView:senderView];
[Utility showMessageHUD:error.localizedDescription];
}];
}
这似乎是一个 iOS 错误,许多其他应用程序也受到影响。
在 iOS 9.3 的主线程上调用时确实会导致死锁(在 iPhone 6 和 iPhone 6 Plus 上测试)。
回溯:
* thread #1: tid = 0x41840, 0x0000000180ac1014 libsystem_kernel.dylib`semaphore_wait_trap + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
* frame #0: 0x0000000180ac1014 libsystem_kernel.dylib`semaphore_wait_trap + 8
frame #1: 0x000000010023fa20 libdispatch.dylib`_dispatch_semaphore_wait_slow + 244
frame #2: 0x0000000180bda934 libxpc.dylib`xpc_connection_send_message_with_reply_sync + 204
frame #3: 0x000000018276a238 MobileCoreServices`_LSStartOpenOperation + 232
frame #4: 0x0000000182791efc MobileCoreServices`-[LSOpenOperation main] + 1160
frame #5: 0x0000000182771bc0 MobileCoreServices`-[LSApplicationWorkspace openURL:withOptions:error:] + 472
frame #6: 0x000000018633cdd8 UIKit`-[UIApplication _openURL:] + 356
frame #7: 0x0000000100096c04 MyApp`__29-[ViewController someMethod]_block_invoke(.block_descriptor=0x0000000125d37e20) + 216 at ViewController.m:57
frame #8: 0x000000010022da7c libdispatch.dylib`_dispatch_call_block_and_release + 24
frame #9: 0x000000010022da3c libdispatch.dylib`_dispatch_client_callout + 16
frame #10: 0x00000001002334e4 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 2096
frame #11: 0x0000000180ef8dd8 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
frame #12: 0x0000000180ef6c40 CoreFoundation`__CFRunLoopRun + 1628
frame #13: 0x0000000180e20d10 CoreFoundation`CFRunLoopRunSpecific + 384
frame #14: 0x0000000182708088 GraphicsServices`GSEventRunModal + 180
frame #15: 0x00000001860f5f70 UIKit`UIApplicationMain + 204
frame #16: 0x00000001000970d0 MyApp`main(argc=1, argv=0x000000016fd6fae8) + 124 at main.m:14
frame #17: 0x00000001809be8b8 libdyld.dylib`start + 4
我发现将整个调用包装在 dispatch_async
块中可以解决问题:
dispatch_async(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
});
我会向 Apple 提交 Radar,然后 post 它会在 Open Radar。
看起来这是用 iOS 9.3.1:
修复的
Fixes an issue that caused apps to be unresponsive after tapping on links in Safari and other apps.
我在 iPad Air 2 / 3 运行 iOS 9.3.5 遇到了同样的问题,JAL 的回答没有解决我的问题。
下面的代码很有魅力。
fileprivate func letApplicationHandleUrl(_ url: URL) {
guard UIApplication.shared.canOpenURL(url) else {
return
}
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
DispatchQueue.global(qos: .userInteractive).async {
UIApplication.shared.openURL(url)
}
}
}
我的应用程序在 iOS 9.3 build 13E233 和 13E234 上调用 openURL
后冻结。
我尝试使用 dispatch_after
,但这并不能解决问题。
这是代码,没什么特别的。
+ (void)someMethod:(UIView *)senderView {
[Utility showLoadingHUDWithText:nil inView:senderView];
[[SomeClient sharedClient] someNetworkAPI:^(id result) {
[Utility hideAllHUDsForView:senderView];
NSDictionary *dict = (NSDictionary *)result;
NSString *someString = dict[@"someKey"];
NSURL *url = [NSURL URLWithString:someString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
} fail:^(NSError *error) {
[Utility hideAllHUDsForView:senderView];
[Utility showMessageHUD:error.localizedDescription];
}];
}
这似乎是一个 iOS 错误,许多其他应用程序也受到影响。
在 iOS 9.3 的主线程上调用时确实会导致死锁(在 iPhone 6 和 iPhone 6 Plus 上测试)。
回溯:
* thread #1: tid = 0x41840, 0x0000000180ac1014 libsystem_kernel.dylib`semaphore_wait_trap + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
* frame #0: 0x0000000180ac1014 libsystem_kernel.dylib`semaphore_wait_trap + 8
frame #1: 0x000000010023fa20 libdispatch.dylib`_dispatch_semaphore_wait_slow + 244
frame #2: 0x0000000180bda934 libxpc.dylib`xpc_connection_send_message_with_reply_sync + 204
frame #3: 0x000000018276a238 MobileCoreServices`_LSStartOpenOperation + 232
frame #4: 0x0000000182791efc MobileCoreServices`-[LSOpenOperation main] + 1160
frame #5: 0x0000000182771bc0 MobileCoreServices`-[LSApplicationWorkspace openURL:withOptions:error:] + 472
frame #6: 0x000000018633cdd8 UIKit`-[UIApplication _openURL:] + 356
frame #7: 0x0000000100096c04 MyApp`__29-[ViewController someMethod]_block_invoke(.block_descriptor=0x0000000125d37e20) + 216 at ViewController.m:57
frame #8: 0x000000010022da7c libdispatch.dylib`_dispatch_call_block_and_release + 24
frame #9: 0x000000010022da3c libdispatch.dylib`_dispatch_client_callout + 16
frame #10: 0x00000001002334e4 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 2096
frame #11: 0x0000000180ef8dd8 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
frame #12: 0x0000000180ef6c40 CoreFoundation`__CFRunLoopRun + 1628
frame #13: 0x0000000180e20d10 CoreFoundation`CFRunLoopRunSpecific + 384
frame #14: 0x0000000182708088 GraphicsServices`GSEventRunModal + 180
frame #15: 0x00000001860f5f70 UIKit`UIApplicationMain + 204
frame #16: 0x00000001000970d0 MyApp`main(argc=1, argv=0x000000016fd6fae8) + 124 at main.m:14
frame #17: 0x00000001809be8b8 libdyld.dylib`start + 4
我发现将整个调用包装在 dispatch_async
块中可以解决问题:
dispatch_async(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
});
我会向 Apple 提交 Radar,然后 post 它会在 Open Radar。
看起来这是用 iOS 9.3.1:
修复的Fixes an issue that caused apps to be unresponsive after tapping on links in Safari and other apps.
我在 iPad Air 2 / 3 运行 iOS 9.3.5 遇到了同样的问题,JAL 的回答没有解决我的问题。
下面的代码很有魅力。
fileprivate func letApplicationHandleUrl(_ url: URL) {
guard UIApplication.shared.canOpenURL(url) else {
return
}
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
DispatchQueue.global(qos: .userInteractive).async {
UIApplication.shared.openURL(url)
}
}
}