OC和Swift混編
OC和Swift的混編,分為兩種情況:
- OC專案中嵌入Swift檔案
- Swift專案中嵌入OC檔案
先來看OC專案中嵌入Swift檔案的情況
新建一基於OC的專案,比如:OC_project
接下來我們建立一個Swift類:BridgeTest.swift,並在裡面新建一個類:Person
-- Person.swift --
import Foundation
// public可以省略,外面同樣可以調得到
// 要OC呼叫到這個Swift類,則@objc不可省略,另外要直接或間接繼承於NSObject
@objc public class Person: NSObject {
// 為了讓OC呼叫,方法同樣需要@objc標示
@objc
func think() -> Void {
print("person can think, it's important.")
}
@objc
func eat() -> Void {
print("person can eat, it's important.")
}
@objc
func drink(_ water: String) -> Void {
print("person can drink \(water), it's important")
}
}
注:這裡的Swift檔名叫BridgeTest.swift,而類名叫Person, 這並不是一個好的命名習慣,一般檔名和類名可以統一,在此寫成不一樣,是為了說明這和Java並不一樣,在java中一個class被命名為public的,則此檔名必須和此public的類名相同,但swift中並沒有這個限制。
在新建這個Swift類時,Xcode會提示生成橋接檔案:
這個橋接檔案的作用主要是在Swift中呼叫OC的,我們暫且不理會,照提示確定即可。這會生成檔案OC_project-Bridging-Header.h
。
然後我們在OC的類裡面呼叫這個Swift類:
#import "ViewController.h"
#import "OC_project-Swift.h" // 如果要使用Swift類,這個標頭檔案需要新增,此檔案是系統自動生成,不可見
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 依賴於Apple自動生成的‘工程名-Swift.h’檔案,本示例中是:OC_project-Swift.h
// 其實在這個檔案中宣告瞭一些Swift到OC的轉換後方法,因此我們可以以OC的呼叫方式呼叫Swift方法
Person *p = [[Person alloc] init];
NSLog(@"%@", p);
[p think];
[p eat];
[p drink:@"咖啡"];
}
注意,一般這樣做就可以了,但Xcode有時候會抽瘋的,因此如果有問題我們需要檢查Xcode的設定:
-
Defines Module :
YES
-
Product Module Name :
yourProjectName
Make sure that your Product Module Name doesn't contain any special characters. -
Install Objective-C Compatibility Header :
YES
Once you've added *.swift file to the project this property will appear in Build Settings。 -
Objective-C Generated Interface Header :
yourProject-Swift.h
This header is auto generated by Xcode -
Objective-C Bridging Header :
$(SRCROOT)/yourProject-Bridging-Header.h
上面是讓OC呼叫Swift方法,下面我們依然基於這個OC專案,讓Swift呼叫OC,在做這個之前我們需要知道一個概念:
Objective-C呼叫Swift: 需要在暴露出來的Swift方法和屬性上加@objc標識,否則不可用;且檔案的類需要繼承自NSObject或NSObject的子類。另外如果仍有問題,需要在工程配置裡面做一些小改動。
Swift呼叫Objective-C: 需要在統一的bridge標頭檔案(YourProjectName-Bridging-Header.h)裡面import,然後即可使用。
在上面的示例中, 使用OC調Swift並不需要使用橋接檔案, 但如果要讓Swift調OC,則需要在這個檔案中import要在Swift中使用的OC類的標頭檔案。
接下來我們新建一個OC的Dog類,讓Swift方法呼叫這個Dog類的方法。
-- Dog.h --
@interface Dog : NSObject
- (void)think;
- (void)eat:(NSString *)food;
@end
-- Dog.m --
@implementation Dog
- (void)think {
NSLog(@"Dog can think, but it's different with person's think");
}
- (void)eat:(NSString *)food {
NSLog(@"%@", [NSString stringWithFormat:@"dog can eat: %@, it's important", food]);
}
@end
然後在BridgeTest.swift中的Person類中新增兩個方法:
@objc
func dogThink() -> Void {
let dog: Dog = Dog()
dog.think()
}
@objc
func dogEat(_ food: String) -> Void {
let dog: Dog = Dog()
dog.eat(food)
}
-- OC_project-Bridging-Header.h --
#import "Dog.h"
-- ViewController.m --
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 依賴於Apple自動生成的‘工程名-Swift.h’檔案
Person *p = [[Person alloc] init];
NSLog(@"%@", p);
[p think];
[p eat];
[p drink:@"咖啡"];
[p dogThink]; // 新增
[p dogEat:@"狗糧"]; // 新增
}
@end
以上是基於OC專案嵌入Swift檔案,接下來我們在Swift專案中嵌入OC檔案
Swift專案中嵌入OC檔案相對比較簡單,新建一基於Swfift的專案,比如:Swift_project, 然後新建OC類,在新建的時候同樣按照系統提示生成bridge檔案。
如果Swift類要呼叫OC,只須在Swift_project-Bridging-Header.h中#import相對應的OC類即可。如果OC類要呼叫Swift, 只需#import "Swift_project-Swift.h"
即可。
示例:
-- Person.h --
@interface Person : NSObject
- (void)think;
- (void)dogThink;
@end
-- Person.m --
#import "Person.h"
#import "Swift_project-Swift.h"
@implementation Person
- (void)think {
NSLog(@"think");
}
- (void)dogThink {
Dog *d = [[Dog alloc] init];
[d think];
}
@end
-- Dog.swift --
import UIKit
@objc
class Dog: NSObject {
@objc
public func think() -> Void {
print("dong think, but different with person")
}
}
-- Swift_project-Bridging-Header.h --
#import "Person.h"
-- ViewController.swift --
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let p: Person = Person()
p.think()
p.dogThink()
}
}
相關文章
- OC和Swift混編經驗Swift
- iOS UMeng OC和Swift混編iOSSwift
- 進階-Swift和OC混編生成 swift pod私有庫Swift
- iOS-OC、Swift混編之橋接檔案iOSSwift橋接
- OC與Swift混編專案遷移到Swift4.2小記Swift
- Objective-C和Swift混編ObjectSwift
- swift 混編 oc 斷點時資料只有變數名稱不顯示值Swift斷點變數
- 雲音樂 Swift 混編 Module 化實踐Swift
- 京東App Swift 混編及元件化落地APPSwift元件化
- OC 與 Swift 相互呼叫Swift
- iOS開發中使用OC和swift的對比iOSSwift
- (轉)OC專案轉Swift指南Swift
- OC,swift,javascript,Dart語言比較SwiftJavaScriptDart
- 今天在object-c 和swift 混編的時候出現錯誤:could not build module foundationObjectSwiftUI
- 2018-07-12 OC 與swift 互相呼叫Swift
- iOS 開發選擇OC還是Swift?iOSSwift
- Covariance, Contravariance以及Generics在 Swift/OC 中的應用.Swift
- oc與swift檔案的相互呼叫方式——橋接Swift橋接
- python與matlab混編PythonMatlab
- C++和MATLAB混編的問題集錦C++Matlab
- 深入小程式系列(三) ReactNative和小程式混編React
- QT creator 中c和c++混編問題QTC++
- iOS Navigation Bar 導航欄折騰記 (Swift&OC)iOSNavigationSwift
- 深入小程式系列之二、Flutter 和小程式混編Flutter
- spring boot kotlin java 混編Spring BootKotlinJava
- OC/Swift/C/C++混合使用的程式設計姿勢SwiftC++程式設計
- 關於C和C++混編的一些心得C++
- cmake混編.c和.cpp需要注意的地方--指定兩種編譯器編譯
- QML::qml與c++混編C++
- Sublime 編寫編譯 swift程式碼編譯Swift
- Swift與OC真正去理解Block解決迴圈引用的技巧SwiftBloC
- flutter和Android混編下出現“No implementation found for method xxxx on channel”錯誤FlutterAndroid
- [混編] iOS原生專案- 接入FlutteriOSFlutter
- WebViewJavascriptBridge JS和OC互動WebViewJavaScriptJS
- iOS Native混編Flutter互動實踐iOSFlutter
- 編譯開源 Swift Foundation 庫編譯Swift
- Swift原始碼專案編譯Swift原始碼編譯
- ubuntu16.04下MATLAB和C++混編(基於ROS,不含VS類別的編譯器)UbuntuMatlabC++ROS編譯