OC與swift混編
前言
蘋果推出swift已經(jīng)兩年多了,到今年的九月份正式發(fā)布了swift的3.0版本,相信很多iOS開發(fā)或多或少已經(jīng)使用過swift,由于維護(hù)的項目時間比較久了,以往都是使用OC開發(fā),現(xiàn)在正在對已有一些功能進(jìn)行改版重寫,索性使用swift來做,以下是在使用OC與swift進(jìn)行混編過程的一些介紹。
一、工程配置
1.Object-C bridging-header
- Object-C bridging-header是什么?
Object-C bridging-header是指OC與swift的橋接文件,它的作用是在swift文件中你可以使用OC文件中聲明(和實現(xiàn))的變量、常量、類、函數(shù)、方法等。
- 怎么使用?
我們現(xiàn)在擁有一個使用OC作為開發(fā)語言的iOS工程,在工程中只有OC相關(guān)的以.h或.m為后綴的文件。
我們用Xcode8打開我們的iOS工程,然后在我們的iOS工程中創(chuàng)建第一個swift文件(command+n或者file->new->file)。
此時會提示我們需要創(chuàng)建一個BridgingHeader文件。
選擇創(chuàng)建,打開bridgingHeader文件可以看到描述Use this file to import your target's public headers that you would like to expose to Swift.
,很明顯這個文件就是用來引入文件到swift的。
想要在swift文件中使用OC文件,直接在這里引入你想導(dǎo)入的OC頭文件就可以了,導(dǎo)入方式和OC文件的相互導(dǎo)入一樣,如下:
#import "OCClassFile.h"
至此,在bridging-header文件中import
相關(guān)OC頭文件,就可以在swift文件中使用OC了。
另外,假如你想給bridging-header文件重命名或者修改它的文件路徑,你可以在build setting中進(jìn)行修改配置,其中Swift Compiler General選項下的Object-C Bridging Header文件路徑是相對路徑,你可以新建一個文件夾或者給bridging-header文件重命名,只需要在這里更新一下新的文件路徑就可以了。
2. Swift.h
- Swift.h是什么
Swift.h文件是指Swift模塊的頭文件,類似于framework的頭文件,它的作用是在OC文件中你可以使用swift中聲明的變量、常量、類等。
- 怎么用
在完成1的步驟后,然后build一次iOS工程,就會自動生成swift.h文件,在任意OC文件中直接引入swift.h文件,就可以使用swift文件中的內(nèi)容了:
#import "ProjectName-Swift.h"
此處注意,工程名中如果存在空格" "或者中劃線"-",需要用下劃線"_"代替。
Swift.h文件是自動生成的,不需要手動創(chuàng)建,這個文件的內(nèi)容也不需要手動管理,在每次build工程時都會被更新。其中只要在swift文件中使用public修飾的類(必須是繼承自NSObject)和方法,都可以在OC中直接使用。
二、混編遇到的問題
- OC NSMutableArray 與 swift Array
在Swift中使用OC類中的方法時,有些參數(shù)會是NSMutableArray的類型,Swift中創(chuàng)建的Array與其類型不一致,此時需要進(jìn)行類型轉(zhuǎn)換。
如果直接進(jìn)行類型轉(zhuǎn)換,Swift編譯器會直接報錯Cannot convert value of type '[SwiftClass]' to expected argument type 'NSMutableArray'
。
一個可行的辦法是,先將Swift中的Array對象轉(zhuǎn)換成NSArray,然后再講NSArray轉(zhuǎn)換成NSMutableArray。
class TestSwift: NSObject {
dynamic func test() -> Void {
let swiftArray = [NSObject]()
let array = swiftArray as NSArray
self.change(array: array.mutableCopy() as! NSMutableArray)
}
dynamic func change(array: NSMutableArray) -> Void {
}
}
- 字符串長度
在OC中的NSString對象會有l(wèi)ength屬性來獲取字符串長度,swift中可以用characters.count
來代替。
// Swift String
let swiftStr = "abc"
assert(swiftStr.characters.count > 0, "字符串長度不合法")
// OC String
let ocStr = NSString.init(string: "abc")
assert(ocStr.length > 0, "字符串長度不合法")
- 字符串子串
// swift
let swiftStr = "abc"
let subStrIndex = swiftStr.index(swiftStr.endIndex, offsetBy: -1)
let subStr = swiftStr.substring(to: subStrIndex)
print(subStr)
// OC
let ocStr = NSString.init(string: "abc")
let ocSubStr = ocStr.substring(to: 2)
print(ocSubStr)
- protocol命名
在使用過程中遇到一個問題是,在OC中有一個代理方法命名是以大寫字母開頭的,導(dǎo)致在swift中實現(xiàn)代理方法時編譯器一直報錯,始終找不到問題,把協(xié)議方法名改為小寫(一般的駝峰命名)后,編譯器不在報錯。