博客
关于我
Swift Runtime分析:还像OC Runtime一样吗?
阅读量:149 次
发布时间:2019-02-27

本文共 2686 字,大约阅读时间需要 8 分钟。

Swift与Objective-C动态性比较:从代码到实践

作为苹果公司于2014年推出的编程语言,Swift逐渐成为iOS和Mac OS开发的重要工具。与Objective-C一样,Swift可以在苹果生态中实现应用程序开发。然而,Swift与Objective-C在动态性方面存在显著差异。本文将从代码实例出发,深入分析Swift和Objective-C的动态性特点,以及如何在实际开发中利用这些特性。

动态性比较:纯Swift类与Objective-C类

在动态性方面,Objective-C的运行时机制允许在类运行时获取方法和属性信息,这使得Objective-C具有高度的动态性。相比之下,Swift的动态性与Objective-C存在显著差异。纯Swift类(如TestASwiftClass)在运行时无法通过Objective-C runtime获取其方法和属性,这与Objective-C的运行时机制有所不同。纯Swift类的函数调用方式更接近C++的vtable机制,通过编译时确定的函数调用方式,这意味着其方法和属性无法通过运行时获取。

而对于继承自NSObject的Swift类(如TestSwiftVC),其动态性得到了Objective-C的支持。由于这些类继承自Objective-C的基类(如UIViewController),它们保留了Objective-C的动态性,可以通过运行时获取其方法和属性。然而,自定义的方法和属性如果没有使用特定的修饰符(如@objc和dynamic),则无法被Objective-C runtime识别和调用。

为什么某些方法无法被获取?

从Objective-C的运行时机制来看,所有可被动态获取的方法都需要遵循TypeEncoding规范。TypeEncoding不仅确定了方法的参数类型,还指定了函数调用时参数入栈所需的内存空间。例如,Objective-C方法的TypeEncoding描述了参数的类型和布局(如v24@0:8@16表示参数共需24个字节,返回值为void,参数类型为id和SEL)。

Swift特有的类型(如Character、String、Tuple等)无法直接映射到Objective-C的TypeEncoding规范。例如,Character和Tuple是Swift特有的基本类型,在Objective-C运行时中无法被正确解释。这导致了这些类型的方法无法被Objective-C runtime识别和调用。

为了克服这一限制,开发者需要在方法和属性前使用@objc标识,并在必要时使用dynamic修饰符。dynamic修饰符的作用是确保方法和属性在运行时可以被动态调用,而不被Swift的静态优化机制干扰。

动态替换(Method Swizzling)的实现

动态替换是利用Objective-C运行时机制的一大优势。通过Method Swizzling,可以在类的运行时替换其方法实现。这对于Swift开发者尤为重要,因为它允许在iOS和Mac OS应用中进行功能扩展。

对于纯Swift类(如TestASwiftClass),Method Swizzling的实现需要在方法前添加@objc和dynamic修饰符。仅凭@objc标识是不够的,必须同时使用dynamic修饰符才能确保方法在运行时能够被替换。例如,在将TestASwiftClass的方法testReturnVoidWithaId替换为自定义实现后,必须在方法前加上@dynamic修饰符,才能通过Objective-C运行时实现动态替换。

对于继承自NSObject的Swift类(如TestSwiftVC),自定义方法如果没有dynamic修饰符,同样无法被替换。这是因为其自定义方法没有被Objective-C runtime识别为动态方法。因此,为了实现Method Swizzling,开发者需要在方法前添加@objc和dynamic修饰符。

Objective-C获取Swift类信息

在Objective-C代码中,使用objc_getClass("TestSwiftVC")会发现返回值为空。这是因为Swift类在Objective-C中使用模块前缀(如TestSwift.TestSwiftVC)。为了正确获取Swift类的信息,Objective-C代码需要使用正确的方式获取模块前缀。

在实际开发中,可以通过在Objective-C代码中定义一个C接口,请求Swift类的信息。例如,可以通过在Swift代码中定义一个@objc接口,返回类的实例。这样,Objective-C代码可以通过这个接口获取到Swift类的信息。

Objective-C替换Swift函数

为了实现动态替换,开发者需要在Objective-C代码中定义替换的方法实现。例如,可以在Objective-C代码中定义void testReturnVoidWithaIdImp(id _self, SEL _command, id _id)方法,并通过Method Swizzling将其替换为Swift实现的方法。

在实际开发中,需要注意以下几点:

  • 在Swift类中,自定义方法需要在前面加上@objcdynamic修饰符。
  • 在Objective-C代码中,替换的方法实现需要与Swift类的方法签名一致。
  • 确保Objective-C代码能够正确地与Swift类进行交互。
  • 通过以上方法,可以实现Swift类和Objective-C代码的动态替换,从而充分发挥两者的优势。

    总结

    通过上述分析可以看出,Swift与Objective-C在动态性方面存在显著差异。纯Swift类没有内置的动态性,但可以通过@objc和dynamic修饰符获得动态性。继承自NSObject的Swift类则保留了Objective-C的动态性,但自定义方法和属性需要额外配置才能被动态调用。

    在实际开发中,开发者需要根据具体需求选择合适的开发方式。例如,在需要动态替换方法时,需要注意Swift类的动态性配置;在需要在Objective-C代码中获取Swift类信息时,需要正确处理模块前缀。

    此外,开发者还需要关注Swift语言的最新发展。随着Swift语言的不断进步,Swift与Objective-C的整合也在不断优化。通过深入理解Swift和Objective-C的特点,开发者可以更好地发挥两者的优势,提升应用开发效率。

    转载地址:http://svhf.baihongyu.com/

    你可能感兴趣的文章
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
    查看>>
    NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
    查看>>
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>
    NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
    查看>>
    NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
    查看>>
    NIH发布包含10600张CT图像数据库 为AI算法测试铺路
    查看>>
    Nim教程【十二】
    查看>>
    Nim游戏
    查看>>
    NIO ByteBuffer实现原理
    查看>>
    Nio ByteBuffer组件读写指针切换原理与常用方法
    查看>>
    NIO Selector实现原理
    查看>>
    nio 中channel和buffer的基本使用
    查看>>