隨著swift越來越被開發(fā)者使用,swift也越來越受歡迎。在實(shí)際開發(fā)中,難免會用到oc和swift一起混編開發(fā)的情況,特別是使用以前的一些oc的庫。那么oc和swift要怎么相互的調(diào)用呢?(以下的例子是在swift項目中說明的)
swift調(diào)用oc
在swift項目中新建一個oc的類,寫了一堆oc的代碼,在swift文件中怎么去使用它呢?
1、當(dāng)我們在swift項目中新建一個oc類的時候,xcode會提示我們要不要同時創(chuàng)建橋接文件,我們點(diǎn)創(chuàng)建,xcode會幫我們自動創(chuàng)建一個橋接文件,文件名格式默認(rèn)為:{targetName}-Bridging-Header.h。targetName為當(dāng)前項目的target的名稱。

當(dāng)然不用xcode自動創(chuàng)建我們也可以自己手動去創(chuàng)建這個文件,并指定路徑就好

2、在橋接文件中#importOC需要暴露給Swift的內(nèi)容,這樣在swift文件中就可以訪問了。

完整代碼如下:
// BKPerson.h 文件
@interface BKPerson : NSObject
@property (nonatomic,copy)NSString* name;
@property (nonatomic,assign)NSInteger age;
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age;
- (void)run;
+ (void)run;
-(void)eat:(NSString*)food otherFood:(NSString*)other;
@end
//BKPerson.m 文件
#import "BKPerson.h"
@implementation BKPerson
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age{
self = [super init];
if (self) {
self.age = age;
self.name = name;
}
return self;
}
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age{
return [[self alloc]initWithName:name age:age];
}
- (void)run{
NSLog(@"%@ run",self.name);
}
+ (void)run{
NSLog(@"preson run");
}
-(void)eat:(NSString*)food otherFood:(NSString*)other{
NSLog(@"%@ eat food:%@",self.name,food);
}
@end
// mian.swift文件
/*
在這里就可以去調(diào)用OC的BKPerson這個類的內(nèi)容了,包括屬性、方法等
*/
var p: BKPerson = BKPerson(name: "Beckhams", age: 18)
p.run()
p.eat("cat", otherFood: "dog")
BKPerson.run()
oc調(diào)用swift
在oc的類中,要怎么使用swift的代碼呢?
1、在swift的代碼要能被oc調(diào)用,其定義的類要繼承自NSObject,函數(shù)要用@objc定義。或者在類的開頭用@objcMembers修飾,這樣類的所有屬性和方法都能被oc訪問。如下圖:

2、xcode已經(jīng)默認(rèn)生成一個用于OC調(diào)用Swift的頭文件,文件名格式是:{targetName}-Swift.h,targetName為當(dāng)前項目的target的名稱。

3、在oc的代碼中導(dǎo)入這個文件,在相應(yīng)的方法中調(diào)用swift的代碼。


4、為啥oc能訪問swift的類呢,swift中定義的類繼承自NSObject到底有啥用?其奧秘在于xcode自動生產(chǎn)的{targetName}-Swift.h中。在該文件中會自動為我們定義的swift類去生產(chǎn)對應(yīng)的oc的類。入下圖:

為啥被oc訪問的swift的類要繼承自NSObject?因?yàn)樵趏c中的類是依賴runtime機(jī)制的,而runtime機(jī)制需要isa指針,只有繼承NSObject才能獲得isa指針。
完整代碼如下:
// 在swift文件中定義一個BKTeacher的類
@objcMembers class BKTeacher: NSObject {
var name: String = "Lucy"
var age: Int = 30
init(name: String, age: Int){
self.name = name
self.age = age
super.init()
}
func run() {
print("\(self.name)--run")
}
func eat(food: String) {
print("\(self.name)--eatFood:\(food)")
}
}
// 在oc文件中導(dǎo)入test-Swift.h,然后在oc的方法里去調(diào)用swift類
#import "BKPerson.h"
#import "test-Swift.h"
-(void)testSwift {
//NSLog(@"testSwift");
BKTeacher* t = [[BKTeacher alloc]initWithName:@"lili" age:31];
NSLog(@"%@老師今年%ld歲了",t.name,t.age);
[t run];
[t eatWithFood:@"蛋糕"];
}