今天使用第三方的时候出现了bug,最后发现是UIApplication openURL的问题。

现象描述:当连接xcode运行项目时,app界面会卡住一会,然后才有响应;当断开xcode时,app界面会卡住一会,然后闪退。

崩溃日志:

Exception Type:  EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d
Triggered by Thread:  0Filtered syslog:
None foundThread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib          0x000000018d48b224 mach_msg_trap + 8
1   libsystem_kernel.dylib          0x000000018d48b09c mach_msg + 72
2   libdispatch.dylib               0x000000018d37cee4 _dispatch_mach_send_and_wait_for_reply + 540
3   libdispatch.dylib               0x000000018d37d2e8 dispatch_mach_send_with_result_and_wait_for_reply + 56
4   libxpc.dylib                    0x000000018d5a4edc xpc_connection_send_message_with_reply_sync + 196
5   Foundation                      0x000000018f0b09cc __NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__ + 12
6   Foundation                      0x000000018f0b0070 -[NSXPCConnection _sendInvocation:withProxy:remoteInterface:withErrorHandler:timeout:userInfo:] + 2940
7   CoreFoundation                  0x000000018e4b2d54 ___forwarding___ + 404
8   CoreFoundation                  0x000000018e3aed4c _CF_forwarding_prep_0 + 92
9   MobileCoreServices              0x000000018fe64fb8 -[LSApplicationWorkspace openURL:withOptions:error:] + 248
10  UIKit                           0x000000019486acac -[UIApplication _openURL:] + 144
11  CouponPurchase                  0x000000010085d27c 0x100000000 + 8770172
12  CouponPurchase                  0x0000000100100dac 0x100000000 + 1052076
13  CouponPurchase                  0x00000001003bf108 0x100000000 + 3928328
14  CouponPurchase                  0x0000000100381008 0x100000000 + 3674120
15  CouponPurchase                  0x00000001003be370 0x100000000 + 3924848
16  CouponPurchase                  0x00000001003be184 0x100000000 + 3924356
17  CouponPurchase                  0x00000001003be2f0 0x100000000 + 3924720
18  CouponPurchase                  0x0000000100368cac 0x100000000 + 3574956
19  CouponPurchase                  0x0000000100368a60 0x100000000 + 3574368
20  CoreFoundation                  0x000000018e4b2d54 ___forwarding___ + 404
21  CoreFoundation                  0x000000018e3aed4c _CF_forwarding_prep_0 + 92
22  UIKit                           0x000000019486bc28 __45-[UIApplication _applicationOpenURL:payload:]_block_invoke + 752
23  UIKit                           0x000000019486b6b0 -[UIApplication _applicationOpenURL:payload:] + 644
24  UIKit                           0x0000000194874474 -[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:] + 6260
25  UIKit                           0x0000000194877bb4 __88-[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:]_block_invoke +

注意这里的异常是__NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__ + 12,等待同步回复。

而且,我注意到一个现象,每当走我自己的路由协议,然后在调用第三方的时候就会出现,而如果直接调用第三方方法就不会出现。

所以,定位到了路由相关的地方。而上面信息中有UIApplication _openURL:] + 144信息。所以,猜测是这个方法多次调用,由于方法没有完成导致的同步等待。

如果你在网上搜一下openURL:,就会出现关于 调用openURL:方法响应慢的解决办法 这些信息。具体的解决办法就是加一个延时。

下面列出测试用例:

为了重现bug,先给项目添加一个ms协议,然后添加如下代码:

- (void)test_111
{NSLog(@"111 - start");[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"ms://www.baidu.com"]];[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"ms://www.baidu.com"]];NSLog(@"222 - end");// 打印日志/*2018-09-11 17:34:45.106242+0800 TestOpenUrl[10813:16592945] 111 - start2018-09-11 17:34:55.161707+0800 TestOpenUrl[10813:16592945] 222 - end*/
}

可以看到,这里日志时间相差了10秒钟。


如果使用了延时呢?

- (void)test_222
{NSLog(@"222 - start");[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"ms://www.baidu.com"]];dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"xxxx"]];});NSLog(@"222 - end");// 打印日志/*2018-09-11 17:36:24.810128+0800 TestOpenUrl[10896:16598430] 222 - start2018-09-11 17:36:24.853829+0800 TestOpenUrl[10896:16598430] 222 - end*/
}

可以看到,这里时间间隔就变得很短了。确实解决了卡顿的问题。


其实还有一种解决方法:

- (void)test_333
{NSLog(@"333 - start");[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"xxx"] options:nil completionHandler:nil];[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"xxx"] options:nil completionHandler:nil];NSLog(@"333 - end");// 打印日志/*2018-09-11 17:37:17.812804+0800 TestOpenUrl[10945:16601725] 333 - start2018-09-11 17:37:17.813552+0800 TestOpenUrl[10945:16601725] 333 - end*/
}

使用新的api也能够解决这个问题。但是该api必要在iOS10以上使用。所以如果你的项目需要适配iOS10以下的系统,还是乖乖的加上延时吧。


虽然延时可以解决这个问题,但是我一直觉得不靠谱,到底延时多久才好呢?其实该问题的关键就是如何知道openURL:方法执行完毕的时机。如果等到openURL:执行完毕之后再调用openURL:方法,就不会出现问题。而openURL:执行完毕的时机,我费尽心思,还是拿不到。。。。

如果哪位大神知道,烦请告知。

上面完整测试用例在这里。

你可能被openURL给坑了相关推荐

  1. app pay开发遇到的坑

    集成apple pay需要的资料: https://developer.apple.com/apple-pay/ about Apple Pay Apple Pay 安全性与隐私政策概览 在开发App ...

  2. 新版本微信分享sdk(1.8.3)踩坑实录

    第一个坑 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString ...

  3. iOS-通俗易懂的微信支付接入和爬坑指南,十分钟轻松搞完

     现在基本所有的App都会接入支付宝支付以及微信支付,也有很多第三方提供给你 SDK帮你接入,但是这种涉及到支付的东西还是自己服务器搞来的好一些,其实搞懂了 逻辑非常的简单,下面直接给大家说说下基本流 ...

  4. Django项目在Linux服务器上部署和躺过的坑

    引言 在各方的推荐下,领导让我在测试环境部署之前开发的测试数据预报平台.那么问题来了,既然要在服务器上部署, 就需要准备: 1.linux服务器配置 2.linux安装python环境搭建与配置 3. ...

  5. iOS开发之第三方分享微博分享、微博分享失败原因总结,史上最新最全第三方分享微博方式实现。 微博分享各种坑总结

    本篇文章项目demo:点击打开链接https://github.com/zhonggaorong/weiboSDKDemo 微博环境的相关搭建,请参照我的这篇博客 : http://blog.csdn ...

  6. iOS端移动支付的一些坑

    已经很久没有写博客了,最近刚好工作比较轻松,希望能重新捡起来. 那么来简单说一下在iOS上做支付的一些东西 ( ̄▽ ̄*) 这里主要说支付宝和微信这样的第三方支付,像iOS本身的支付不做探究,话说,这个 ...

  7. 记录Unity和C#遇到的坑(持续更新)

    改特效的startLifetime 特效是沿直线发射粒子, 需求是用startLifetime控制特效的长度 这样, 长度不是瞬间达到目标长度, 而是会缓慢变化到目标长度 eff.main.start ...

  8. weex 一个传说级巨坑-- 2018最新版weex踩坑指南(weex navigator 多界面跳转)

    先说结论,本人极度非常 不推荐weex作为任何商用开发 有很多人会说了... 你瞎扯.. 你看别人阿里.. 啊飞猪... 啊那个支付宝... 人家不是用得好好的么... 当然这也是我们公司作为技术选型 ...

  9. electron 桌面端业务中的小结(坑)

    文章目录 简介 安装electron依赖 本地数据库选择 indexedDB 封装的库 SQLite Lowdb electron-store electron-json-storage-alt.el ...

最新文章

  1. 进入Win8安全模式的几个办法
  2. 在flask上使用websocket
  3. 软件测试成功之本:项目风险的监控
  4. 使用JDBCTemplate实现与Spring结合,方法公用 ——Emp实现类(EmpDaoImpl)
  5. Windows在安装builtwith时遇到问题
  6. hash表冲突处理方法
  7. 【转】Java 单例模式详解
  8. linux 截取列_Linux 常用命令汇总
  9. 附件下载原来如此简单
  10. sharepoint2019文件服务器,在多台服务器上安装 SharePoint Server 2016 或 SharePoint Server 2019...
  11. 新唐NUC980使用记录:向内核添加USB无线网卡驱动(基于RTL8188EUS)
  12. 调用百度地图API去掉地图左下角的百度LOGO方法
  13. 深入浅出java web_深入浅出javaWeb实战第1讲Web的概念及其演变(上)
  14. WTS:基于Web的Terminal控制台
  15. 第五篇 《小强升职记》
  16. 海盗号推荐 | 十分钟读懂币圈必读书籍:《区块链十年》
  17. python frame用法_Pandas Series.to_frame()用法介绍
  18. CAD设置命令框的字体
  19. OpenJudge1758 二叉树
  20. 夏培肃对计算机科学发影响,夏培肃:我国计算机领域的先驱者

热门文章

  1. JCG836pro路由器刷入breed
  2. B-树和B+树的区别
  3. day03 文件操作 函数 参数 返回值 作用域和名称空间 global和nonlocal
  4. web前端工具(配色图片图标)
  5. 为期两个月的MATLAB与ROS联合仿真探索总结——因为热爱,所以无所畏惧
  6. 超市收银系统服务器搭建教程,超市收银系统快速收银步骤? 你需要学习了
  7. Beosin EOS-IDE 升级用户体验及常见问题答疑
  8. 2021 年使用 WordPress 作为 CMS 的 25 个热门网站
  9. 微信小程序上传阿里云视频文件流程及代码
  10. 计算机会显示机械硬盘丢失,Win10机械硬盘突然消失,无法检测到解决方案