目录
- 版本
- Swift调用Objective-C
- Objective-C调用Swift
- 简单分析
版本
Xcode 11.3.1
Swift 5.1.3
Swift调用Objective-C
新建一个Swift工程,然后新建一个Objective-C文件,然后会有桥接头文件的提示(如果不是新建文件,没有这个提示,我们可以自己创建,后文介绍。):
创建桥接头文件
创建之,然后就多了个头文件:
目录
Person.h:
@interface Person : NSObject
- (void)sayHello;
@end
Person.m:
#import "Person.h"
@implementation Person
- (void)sayHello {
printf("Person say hello\n");
}
@end
在SwiftAndOC-Bridging-Header.h文件中引用OC头文件:
#import "Person.h"
先⌘+B编译一下,然后在ViewController.swift中就可以引用OC对象了:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let person = Person()
person.sayHello()
}
}
运行之,打印:
Person say hello
Objective-C调用Swift
新建一个Cat.swift文件:
import UIKit
class Cat: NSObject {
@objc func sayHello() { // @objc的作用后文介绍
print("Cat say hello")
}
}
先⌘+B编译一下,然后我们想在Person.m中调用它,需引入SwiftAndOC-Swift.h头文件:
#import "Person.h"
#import "SwiftAndOC-Swift.h"
@implementation Person
- (void)sayHello {
printf("Person say hello\n");
Cat *cat = [[Cat alloc] init];
[cat sayHello];
}
@end
SwiftAndOC-Swift.h是系统创建的文件,后文介绍。
运行之,打印:
Person say hello
Cat say hello
简单分析
1. XXX-Bridging-Header.h
当我们需要在Swift中引用OC的时候,需要在 XXX-Bridging-Header.h的桥接文件import OC的.h文件。
如果不是新建OC文件,则系统不会帮我们创建这个桥接文件,这时我们就需要手动创建这个桥接文件了。
新建文件:
然后命名为XXX-Bridging-Header.h(XXX一般为你的工程名)。在TARGETS中的Objective-C Bridging Header一栏里填入刚才创建的文件名:
关联桥接文件.png
2. XXX-Swift.h
当我们需要在OC中引用Swift的时候,需要import XXX-Swift.h文件。
而这个文件是系统帮我们创建好了的。在上图中我们自建的桥接文件下一栏,有个SwiftAndOC-Swift.h,这个文件正是系统为我们创建的,且这个文件我们不需去改动。我们可以按住⌘然后点击这个文件,去看看里面的内容。
可以看原本的Person这个OC类已经转化为Swift类型了:
SWIFT_CLASS("_TtC10SwiftAndOC3Cat")
@interface Cat : NSObject
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
但是这时是没有sayHello这个方法的。我们还需要在引用到的Swift函数前面加关键字@objc:
class Cat: NSObject {
@objc func sayHello() {
print("Cat say hello")
}
}
如此这般,原本的Swift函数就转变成XXX-Swift.h中的OC方法了。编译后再次查看XXX-Swift.h:
SWIFT_CLASS("_TtC10SwiftAndOC3Cat")
@interface Cat : NSObject
- (void)sayHello;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
现在,我们明白了为什么之前在相互引用之前都先编译一下了。因为只有在编译后,我们在写代码的时候系统才会给出关联提示:
关联提示.png
网友评论