zoukankan      html  css  js  c++  java
  • JSPatch 遇上swift

    swift使用JSPatch要点:

    • 继承自NSObject的Swift类,其继承自父类的方法具有动态性,其他自定义方法、属性需要加dynamic修饰才可以获得动态性(public属性除外) 例子可参看项目中的:demo1.js, demo1_1.js, demo2.js
    • 纯Swift类没有动态性。也就是说无法重写纯swift类的方法和属性。demo6,demo7
      • JSPatch在进行到overrideMethod进行方法实现IMP替换时要求class实现NSCoping协议,而不继承自NSObject的swift类是不遵循该协议的,因此崩溃。
      • static void _initJPOverideMethods(Class cls) {
            if (!_JSOverideMethods) {
                _JSOverideMethods = [[NSMutableDictionary alloc] init];
            }
            if (!_JSOverideMethods[cls]) {
                _JSOverideMethods[(id<NSCopying>)cls] = [[NSMutableDictionary alloc] init];
            }
        }

      • 此处JSPatch在初始化缓冲区的时候将Class作为Dictionarykey进行保存,而Dictionary在设置key-value时会拷贝 key值,所以会导致给一个不遵循NSCoying协议的对象发送了copyWithZone:消息,导致崩溃。

      • 在github上已有朋友给JSPatch的作者提交了issue,暂时没有什么解决办法,希望swift 3.0出来之后能够有好的解决办法。issue地址
      • swift中runtime相对OC中的runtime动态性大大减弱;objc_msgSend函数无法用于 Swift object,这个导致JSPatch实现方法调用(消息转发)的基础机制在 Swift 中失效了,这也是热修复真正无解的地方,也是最致命的。
    • 同理protocol实现的类也是没有动态性,除非继承自NSObject对像,又回到了上条结论 demo6
    • 对通用性的测试:swift中block的使用,view的简单动画, GCD都是支持的   demo4
      • 注意:block体中如果使用self,比如用var来重新定义变量。GCD,animation在swift和oc中都不需要,但在js中则需要将其self重新定义 
    • 扩展遵循其扩展类的动态性  demo5
    • 若方法的参数/属性类型为 Swift 特有(如 Character / Tuple),则此方法和属性无法通过 JS 调用。

    总结:

    • 只支持调用继承自 NSObject 的 Swift 类,并且需要使用dynamic关键字标记属性和方法才具有动态性,若方法的参数/属性类型为 Swift 特有(如 Character / Tuple)则无法通过JS调用
    • 多用类方法替代静态方法,使其具有动态性
    • 尽量避免纯Swift类,使用继承NSObject的swift类使其具有动态性
    • 以上几点都是针对Swift APP
    • Demo地址

    相关文档:

  • 相关阅读:
    [译]kendoui
    [LeetCode] 74 Search a 2D Matrix(二分查找)
    [LeetCode] N皇后问题
    [LeetCode] 5 Longest Palindromic Substring
    [LeetCode] 98 Validate Binary Search Tree
    [LeetCode] 119 Pascal's Triangle II
    [LeetCode] 二叉树相关题目(不完全)
    排序方法的分类和实现
    已知前序(后序)遍历序列和中序遍历序列构建二叉树(Leetcode相关题目)
    拓扑排序(附LeetCode题目)
  • 原文地址:https://www.cnblogs.com/jinfengboy/p/5819802.html
Copyright © 2011-2022 走看看