在Apple官方的《Using Swift with Cocoa and Objectgive-C》一書中詳細地介紹瞭如何在Objective-C中使用Swift的類以及如何在Swift中使用Objective-C中的類。在後半部分也介紹瞭如何在Swift中使用C函數,不過對於如何在C語言中使用Swift函數卻隻字未提。這裏我就爲你們分享一下如何在C語言中調用Swift函數。swift
咱們首先要知道的是,全部Swift函數都屬於閉包。其次,Swift函數的調用約定與Apple爲Clang編譯器貢獻的Blocks語法一致。所以,咱們須要經過使用Blocks調用約定將Swift函數導入到C語言中。因爲在C語言中沒法直接聲明Blocks調用約定的函數,所以咱們能夠經過定義全局的指向Blocks的對象指針來實現。閉包
下面咱們建立一個名爲SwiftTest的macOS系統上的Swift工程。而後新建一個名爲test.c的C源文件,若是Xcode沒有彈出是否新建bridging-header文件,那麼咱們能夠新增一個Objective-C源文件,最後把它給移除。這裏,咱們必須在工程裏包含SwiftTest-Bridging-Header.h這個頭文件。async
而後咱們編輯此頭文件:ide
extern void (^ __nonnull SwiftFunc)(void);
extern void CFuncTest(void);
這裏聲明的全局指向void(^)(void)類型的Block的引用對象。函數
而後咱們再看test.c源文件:測試
void (^SwiftFunc)(void) = NULL; void CFuncTest(void) { SwiftFunc(); }
咱們定義SwiftFunc全局對象,將它初始化爲空。spa
而後在ViewController.swift中編輯如下內容:指針
// 這裏是對SwiftFunc的實現 private func swiftFuncImpl() { print("This is a Swift function!"); } class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() // 這裏對定義在test.c中的SwiftFunc進行初始化 SwiftFunc = swiftFuncImpl // 這裏用dispatch_async來測試SwiftFunc是否一直被hold着 dispatch_async(dispatch_get_main_queue()) { CFuncTest() } } }
當調用了test.c中定義的CFuncTest函數以後,該函數裏將直接調用SwiftFunc這一Block引用對象,從而達到了在C語言中調用了Swift中函數的目的。code