美文网首页
混编扫盲

混编扫盲

作者: 李永开 | 来源:发表于2023-08-01 21:09 被阅读0次

    一. 在同一个app或者Unit Test混编

    我们先建两个文件, 一个oc, 一个swift

    @interface FirstOC : NSObject
    - (void)logOC;
    @end
    
    @implementation FirstOC
    - (void)logOC {
        NSLog(@"%@", _cmd);
    }
    @end
    
    class FirstSwift : NSObject {
        @objc func logSwift() {
            print(#function)
        }
    }
    

    1.1 oc调用swift

    我们需要在oc文件里面这样使用, 导入#import "hybirdTest-Swift.h"就能使用使用swift这个类了。 其中hybirdTest是项目名称,-Swift.h是固定后缀。

    #import "hybirdTest-Swift.h"
    
    1.1.1 为啥呢?

    打开看看, 搜索FirstSwift,发现xcode将swift代码导出为oc的方法声明,这样就能编译通过了。

    图片.png

    1.2 swift调用oc

    我们需要在hybirdTest-Bridging-Header中导入swift类需要用到的OC类, 这样就可以做到swift调用oc了。

    图片.png
    1.2.1 为啥呢?

    具体实现不详, 猜测是找到SWIFT_OBJC_BRIDGING_HEADER这个环境变量,然后将其中的OC代码导出为swift的声明

    图片.png

    二. 不同组件或者同一组件之间的混编

    早些时候都是主工程和组件都是OC代码的时候, 我们要使用组件代码,只需要`#import<A/A.h>即可。
    但是后来swift的比重越来越大, 怎么引用组件中swift的代码就成了一个问题。

    2.1 头文件的各种导入方式

    • #include:C/C++导入头文件的关键字, 原理是简单粗暴的将要导入的文件代码复制到当前文件,会导致重复导入,效率低下
    • #import:OC的头文件导入方式,它能保证同一个头文件不会被重复包含
    • @class: 告诉编译期我有这个类,先别急着报错,我会在稍后的文件里#import具体的类实现的,可以解决头文件的相互包含的问题
    • @import: OC中用来导入模块的方式
    • import: swift中用来导入模块的方式

    2.2 search paths

    • Header search paths:和下面的差不多,如果编译器不支持user headers概念,会从header search paths中去寻找
    • user header search paths:和上面差不多
    • use header maps:生成hmap文件,记录了头文件名称及其对应的磁盘位置
    • 上面3个一般配合使用

    • Enable Modules: 允许使用模块,也就是可以使用@import和import

    2.3 组件A引用混编的组件B失败

    在A的podspec中添加以下代码

        search_paths = ["\"${PODS_ROOT}/Headers/Public/ZZUI\"",
                        "\"${PODS_ROOT}/Headers/Private/ZZUI\"",
                        ]
        ss.pod_target_xcconfig = {
          'HEADER_SEARCH_PATHS' => search_paths.join(' '),
          'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES'
        }
    

    对比下xcconfig, 发现HEADER_SEARCH_PATHS多了ZZUI,这样就能找到了。

    //加了代码
    HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/ModuleSearchFilter" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SQLiteRepairKit" "${PODS_ROOT}/Headers/Public/WCDB" "${PODS_ROOT}/Headers/Public/WCDBOptimizedSQLCipher" "${PODS_ROOT}/Headers/Public/ZZUI" "${PODS_ROOT}/Headers/Private/ZZUI"
    
    //没加代码
    HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/ModuleSearchFilter" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SQLiteRepairKit" "${PODS_ROOT}/Headers/Public/WCDB" "${PODS_ROOT}/Headers/Public/WCDBOptimizedSQLCipher"
    

    2.4 SWIFT_INCLUDE_PATHS

    需要注意的点:

    引用组件文件的时候,尽量不要使用import"", 这样会导致开启module的时候报错

    参考:

    综合篇
    clang官网中的module实现
    oc swift的api交互
    详解
    错误排查
    实战一下

    相关文章

      网友评论

          本文标题:混编扫盲

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