一. 在同一个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的时候报错
网友评论