混編掃盲

一. 在同一個(gè)app或者Unit Test混編

我們先建兩個(gè)文件, 一個(gè)oc, 一個(gè)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調(diào)用swift

我們需要在oc文件里面這樣使用, 導(dǎo)入#import "hybirdTest-Swift.h"就能使用使用swift這個(gè)類(lèi)了。 其中hybirdTest是項(xiàng)目名稱(chēng),-Swift.h是固定后綴。

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

打開(kāi)看看, 搜索FirstSwift,發(fā)現(xiàn)xcode將swift代碼導(dǎo)出為oc的方法聲明,這樣就能編譯通過(guò)了。

圖片.png

1.2 swift調(diào)用oc

我們需要在hybirdTest-Bridging-Header中導(dǎo)入swift類(lèi)需要用到的OC類(lèi), 這樣就可以做到swift調(diào)用oc了。

圖片.png
1.2.1 為啥呢?

具體實(shí)現(xiàn)不詳, 猜測(cè)是找到SWIFT_OBJC_BRIDGING_HEADER這個(gè)環(huán)境變量,然后將其中的OC代碼導(dǎo)出為swift的聲明

圖片.png

二. 不同組件或者同一組件之間的混編

早些時(shí)候都是主工程和組件都是OC代碼的時(shí)候, 我們要使用組件代碼,只需要`#import<A/A.h>即可。
但是后來(lái)swift的比重越來(lái)越大, 怎么引用組件中swift的代碼就成了一個(gè)問(wèn)題。

2.1 頭文件的各種導(dǎo)入方式

  • #include:C/C++導(dǎo)入頭文件的關(guān)鍵字, 原理是簡(jiǎn)單粗暴的將要導(dǎo)入的文件代碼復(fù)制到當(dāng)前文件,會(huì)導(dǎo)致重復(fù)導(dǎo)入,效率低下
  • #import:OC的頭文件導(dǎo)入方式,它能保證同一個(gè)頭文件不會(huì)被重復(fù)包含
  • @class: 告訴編譯期我有這個(gè)類(lèi),先別急著報(bào)錯(cuò),我會(huì)在稍后的文件里#import具體的類(lèi)實(shí)現(xiàn)的,可以解決頭文件的相互包含的問(wèn)題
  • @import: OC中用來(lái)導(dǎo)入模塊的方式
  • import: swift中用來(lái)導(dǎo)入模塊的方式

2.2 search paths

  • Header search paths:和下面的差不多,如果編譯器不支持user headers概念,會(huì)從header search paths中去尋找
  • user header search paths:和上面差不多
  • use header maps:生成hmap文件,記錄了頭文件名稱(chēng)及其對(duì)應(yīng)的磁盤(pán)位置
  • 上面3個(gè)一般配合使用

  • 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'
    }

對(duì)比下xcconfig, 發(fā)現(xiàn)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"

//沒(méi)加代碼
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

需要注意的點(diǎn):

引用組件文件的時(shí)候,盡量不要使用import"", 這樣會(huì)導(dǎo)致開(kāi)啟module的時(shí)候報(bào)錯(cuò)

參考:

綜合篇
clang官網(wǎng)中的module實(shí)現(xiàn)
oc swift的api交互
詳解
錯(cuò)誤排查
實(shí)戰(zhàn)一下

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容