OC和Swift混編 - 在Swift中實現OC中靜態常量和巨集的效果
前言:
言歸正傳:
首先,我們來了解一下OC和Swift和本文相關的一些區別
OC:
- 靜態常量,一般用於固定的一些數值或者字串,對於不是隻在類內部使用的靜態常量,需要在名稱前加類名或者檔名(如程式碼塊中的
HGNote
),這樣做是為了避免和其他檔案中的靜態常量/變數名衝突,也更易讀;
static const int HGNoteId = 53; static NSString *const HGNoteName = @"騎著驢繞臺灣島一圈";
- 巨集定義
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
Swift:
-
全域性常量/變數
使用
let/var
修飾, 定義在類、結構體等的外部
import UIKit //全域性常量 let isIPad: Bool = UIDevice.current.userInterfaceIdiom == .pad //可計算的全域性變數(很少使用通常的的全域性變數,那是不安全的),這裡為什麼使用只讀的全域性變數呢?因為有些專案可以轉屏,有的專案適配了ipad的,轉屏和分屏會使螢幕的尺寸發生改變。 //錯誤寫法1: var screenWidth = UIScreen.main.bounds.size.width //錯誤寫法2: let screenWidth = UIScreen.main.bounds.size.width //正確寫法: var screenWidth: CGFloat { return UIScreen.main.bounds.size.width }
- 類屬性
class HGConstant: NSObject { //在屬性前+@objc將可以在OC檔案中使用,在用的OC檔案中匯入標頭檔案(#import "ProjectName+Swift.h")即可呼叫 //類不可變屬性 @objc static let identityImageDimension: CGFloat = 15 //類計算屬性 @objc static var screenWidth: CGFloat { return UIScreen.main.bounds.size.width } }
不同點:
- OC檔案中的
靜態常量
是可以在Swift檔案中使用的,把相關的標頭檔案匯入到OC和Swift的橋接檔案
中即可在Swift中呼叫;而巨集
不能在Swift中使用; - Swift檔案中的全域性變數/常量由於不能在其頭部加
@objc
, 所以不能在OC檔案中使用;類屬性可以在OC檔案中使用。
專案實戰場景:
專案採用混編的方式,並在之後的開發中除了對之前的OC程式碼修改外,新增的檔案全部使用Swift開發,而之前需要在OC中定義的 全域性常量
和 巨集
,今後會換一種方式定義在 HGConstant.swift
檔案中, 在這個檔案中我們定義一些 全域性常量
、 可計算的變數
和 類屬性
,來相容OC和Swift兩種語言的呼叫;
下面使用一張圖來標記一下實際的使用情況:

圖解
補充:OC中沒有類屬性和計算屬性的概念,那為什麼在Swift中定義的類屬性可以在OC中訪問呢?
我們來看看Xcode幫我們做了點什麼:這裡我用另一個檔案做示範

因為後面的值是定值,所以這裡沒有使用類計算屬性

找到 ProjectName+Swift.h 這個檔案

可以看到類屬性已經被轉換成了類方法

在OC檔案中呼叫
所以,除了類屬性之外,你也可以使用類方法的方式相容OC和Swift,只不過在Swift中呼叫的時候方法名後跟一個(), 有點不完美,所以還是建議大家使用類屬性。