首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Swift、Objective-C 與 C 語言混合編程完整指南

     編輯:關於C

前言

自 Swift 推出以來,新專案可直接使用 Swift 開發,但實際專案中常會遇到需整合既有 Objective-C 類別、封裝模組或第三方 Objective-C 庫的情況。此時「混合編程」便成為關鍵技術,自 iOS 8 起正式支援。本文將系統說明在同一專案目錄下,Swift 調用 Objective-C、Swift 調用 C 函式、Objective-C 調用 Swift 三種核心混編場景,並記錄實作過程中的關鍵細節與避坑指南。

專案準備與檔案建立

1. 建立 Swift 專案與類別

以 SwiftTest 為專案名稱建立 Swift 專案。新增 Swift 類別時,務必選擇 Cocoa Touch Class 並繼承 NSObject,否則 Objective-C 無法直接識別該類別。另需注意 Target 選擇 iOS Source,預設的 OS X Source 會導致匯入 Cocoa 模組而非 UIKit,造成混編錯誤。

2. 建立 Objective-C 類別與橋接頭文件

在 Swift 專案中新增 Objective-C 類別時,Xcode 會提示建立橋接頭文件(專案名-Bridging-Header.h),點選 Create Bridging Header 即可自動生成。若無提示,可手動新增 Header 檔並在 Target → Build Settings → Objective-C Bridging Header 設定路徑(如 SwiftTest/JeckHeader.h)。橋接頭文件是 Swift 存取 Objective-C 與 C 宣告的關鍵。

3. 建立 C 語言檔案

新增 C File 時,勾選 Also create a header file 可同時產生 .h 與 .c,便於後續在橋接頭文件中匯入。本文分別建立含頭文件(CClass.h/.c)與無頭文件(CClassNo.c)兩種情況示範。

核心程式碼實作

Swift 類別(供 Objective-C 呼叫)

// SwiftClass.swift
import UIKit
class SwiftClass: NSObject {
    func sayHello(name: String) -> String {
        return "Hello \(name)!"
    }
}

Objective-C 類別(實作方法與 C 函式)

// OCClass.h
#import 
@interface OCClass : NSObject
int sum2(int a, int b);
- (void)desc22;
- (void)desc2;
@end

// OCClass.m
#import "OCClass.h"
#import "SwiftTest-Swift.h"  // 自動生成的 Swift 模組頭文件
@implementation OCClass
- (void)desc22 {
    int (^block)(int, int) = ^(int a, int b) { return a + b; };
    int result = block(10, 40);
    NSLog(@"Swift呼叫OC方法輸出 result:%d", result);
    SwiftClass *sc = [[SwiftClass alloc] init];
    NSString *str = [sc sayHello:@"jeck"];
    NSLog(@"OC呼叫Swift函式輸出 %@", str);
}
- (void)desc2 {
    int (^block)(int, int) = ^(int a, int b) { return a + b; };
    int result = block(10, 40);
    printf("Swift呼叫OC方法輸出 result:%d\n", result);
}
int sum2(int a, int b) { return a + b; }
@end

C 語言實作(含/不含頭文件)

// CClass.h
#ifndef CClass_h
#define CClass_h
#include 
int sum3(int a, int b);
void desc3();
#endif

// CClass.c
#include "CClass.h"
int sum3(int a, int b) { return a + b; }
void desc3() {
    int (*p)(int, int) = sum3;
    int result = p(10, 10);
    printf("Swift呼叫含頭文件C函式輸出:%d\n", result);
}

// CClassNo.c(無頭文件)
#include 
int sum1(int a, int b) { return a + b; }
void desc1() {
    int (*p)(int, int) = sum1;
    int result = p(10, 20);
    printf("Swift呼叫無頭文件C函式輸出 result:%d\n", result);
}

橋接頭文件設定

// SwiftTest-Bridging-Header.h
#import "CClass.h"
#import "OCClass.h"
// 無頭文件的 C 函式需在此前向宣告
void desc1();
int sum1(int a, int b);

Swift 呼叫 Objective-C 與 C

// ViewController.swift
import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Swift 呼叫 OC 方法
        let oc = OCClass()
        oc.desc2()
        oc.desc22()
        let sum2Result = sum2(10, 1)
        print("Swift呼叫OC類別中的C函式輸出:\(sum2Result)")
        // Swift 呼叫無頭文件 C 函式
        desc1()
        let sum1Result = sum1(10, 2)
        print("Swift呼叫無頭文件C函式輸出:\(sum1Result)")
        // Swift 呼叫含頭文件 C 函式
        desc3()
        let sum3Result = sum3(10, 3)
        print("Swift呼叫含頭文件C函式輸出:\(sum3Result)")
    }
}

執行結果與關鍵總結

程式成功編譯執行,輸出結果顯示各跨語言呼叫均正常運作。關鍵重點:

  1. 橋接頭文件必須正確建立並配置,將需暴露的 Objective-C 與 C 頭文件(或無頭文件時的前向宣告)匯入其中。
  2. Objective-C 呼叫 Swift 依賴自動生成的模組頭文件(專案名-Swift.h),此文件不顯示於專案導航器,但可 Cmd+Click 跳轉查看。
  3. Swift 類別必須繼承 NSObject 或標註 @objc,否則不會被編譯進模組頭文件,導致 Objective-C 找不到宣告。
  4. 可在 Target → Build Settings → Packaging → Product Module Name 確認/設定模組名稱,頭文件命名即依此而定。

掌握上述機制,即可在專案中靈活混用 Swift、Objective-C 與 C,最大化程式碼復用與開發效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved