美文网首页
JLRoutes 与 Swift 结合使用遇到的一个 Bug

JLRoutes 与 Swift 结合使用遇到的一个 Bug

作者: 我是与非门 | 来源:发表于2016-08-04 20:06 被阅读0次

问题表现

在 Swift 2.x 版本中,注册 JLRoutes 时调用下边的方法,在 Route URL 时会崩溃:

+ (void)addRoute:(NSString *)routePattern handler:(BOOL (^__nullable)(NSDictionary<NSString *, NSString *> *parameters))handlerBlock;

在网上已经有人反馈这个问题了,issue 在这里。目前官方还没有解决这个问题。

原因分析

通过崩溃日志分析(引用 issue

thread #1: tid = 0xbbf578, 0x000000010cb4855f libswiftCore.dylib`swift_bridgeNonVerbatimFromObjectiveC + 255, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
frame #0: 0x000000010cb4855f libswiftCore.dylib`swift_bridgeNonVerbatimFromObjectiveC + 255
frame #1: 0x000000010cb43f70 libswiftCore.dylib`deallocateBuffer value witness for Swift.LazyMapCollection + 16
frame #2: 0x000000010ce63da1 libswiftFoundation.dylib`Swift._forceBridgeFromObjectiveC <A> (Swift.AnyObject, A.Type) -> A + 385
frame #3: 0x000000010ce63b80 libswiftFoundation.dylib`static (extension in Foundation):Swift.Dictionary.(_forceBridgeFromObjectiveC (__ObjC.NSDictionary, result : inout Swift.Optional<Swift.Dictionary<A, B>>) -> ()).(closure #1) + 144
frame #4: 0x000000010ce60624 libswiftFoundation.dylib`partial apply forwarder for static (extension in Foundation):Swift.Dictionary.(_forceBridgeFromObjectiveC (__ObjC.NSDictionary, result : inout Swift.Optional<Swift.Dictionary<A, B>>) -> ()).(closure #1) + 100
frame #5: 0x000000010bd681e6 CoreFoundation`__65-[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:]_block_invoke + 102
frame #6: 0x000000010bd680af CoreFoundation`-[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 159
frame #7: 0x000000010ce4fb4e libswiftFoundation.dylib`static (extension in Foundation):Swift.Dictionary._forceBridgeFromObjectiveC (__ObjC.NSDictionary, result : inout Swift.Optional<Swift.Dictionary<A, B>>) -> () + 558
frame #8: 0x000000010ce4f87b libswiftFoundation.dylib`Foundation._convertNSDictionaryToDictionary <A, B where A: Swift.Hashable> (Swift.Optional<__ObjC.NSDictionary>) -> Swift.Dictionary<A, B> + 75
frame #9: 0x00000001046ba40d Imgur`thunk + 77 at Routing.swift:0
frame #10: 0x0000000108461954 JLRoutes`+[JLRoutes routeURL:withController:parameters:executeBlock:](self=JLRoutes, _cmd="routeURL:withController:parameters:executeBlock:", URL="aaaaaa -- mgur://imgur.com", routesController=0x00007f8b14d20ae0, parameters=0x0000000000000000, executeBlock=YES) + 2740 at JLRoutes.m:551

和调试可以发现,上文中注册方法的参数 handlerBlock 里的 NSDictionarykeyvalue 都被限定为了 NSString类型。
而在真正执行 Route 操作时,方法
+ (BOOL)routeURL:(NSURL *)URL withController:(JLRoutes *)routesController parameters:(NSDictionary *)parameters executeBlock:(BOOL)executeBlock
中对参数的解析,却犯了两个错误:

  1. kJLRouteURLKey 对应的 value 解析成了 NSURL 类型(代码是 finalParameters[kJLRouteURLKey] = URL;
  2. kJLRouteNamespaceKey 对应的 value 有可能会被解析成 NSNull,对应的代码是 finalParameters[kJLRouteNamespaceKey] = strongParentRoutesController.namespaceKey ?: [NSNull null];

从而导致在 didRoute = route.block(finalParameters); 代码调用中, block 传入的 finalParameters 的类型与之前注册传入的 Swift 参数类型不一致,发生了崩溃。

解决方法

解决方法有两种,

  1. handlerBlock 的字典类型的 NSString 限制去掉,这种方法需要作者修改源码。GitHub 上已经有开源的修改了。
  2. 不修改源码的情况下,我们可以用 OC 语言添加一个中间层,将 1 中修改后的方法,作为中间层的类方法,该方法的实现里,直接调用 JLRoutes 的方法。然后在 Swift 代码中,用中间层来注册 Route。

建议可以先采用 2 的方式,等作者修改后,再去掉这个中间层即可。

相关文章

  • JLRoutes 与 Swift 结合使用遇到的一个 Bug

    问题表现 在 Swift 2.x 版本中,注册 JLRoutes 时调用下边的方法,在 Route URL 时会崩...

  • 自定义Scheme、JLRoutes路由跳转

    iOS——Scheme是什么、怎么自定义Scheme、JLRoutes的使用 JLRoutes路由跳转

  • Spark&Mysql bug分析

    Spark&Mysql bug分析 今天在看到spark与mysql结合使用文档,想起来去年年底处理的一个bug。...

  • OpenUrl

    iOS-使用URL Schemes,进行应用之间跳转iOS - JLRoutes路由跳转官方文档JLRoutes ...

  • 2020-04-23

    JLRoutes的另类使用及解析 一、简介 JLRoutes是一个基于块的API的URL路由库。 它旨在使您以最少...

  • 谈谈Swift与Objective-C混编

    在实际项目的工程中,Swift与Objective-C文件都可以无缝结合。 Swift工程里使用Objective...

  • OC与Swift混编

    在写React Native项目中,遇到一个问题,就是OC与Swift的混编,之前都是在Swift文件中使用.h文...

  • Moya使用

    暂不深入学习参考文章:Swift - RxSwift的使用详解49(结合Moya使用1:数据请求)Swift - ...

  • 使用 Swift 语言编程的优缺点

    我们的 Swift 项目上线已经有一段时间了。结合目前 Swift 的使用情况,总结下其与 Objective-C...

  • Swift Alamofire与Moya的结合使用

    前提先熟悉Alamofire的基本使用 Swift 的 Alamofire 与 Objective-C 的 AFN...

网友评论

      本文标题:JLRoutes 与 Swift 结合使用遇到的一个 Bug

      本文链接:https://www.haomeiwen.com/subject/emxhsttx.html