接上篇文章:iOS 快速从OC过渡到Swift,由理论到实战-Swift基础
OC和Swift混编
a. Swift 和 OC 的映射关系
Swift 兼容来大部分 OC,当然还有一些 Swift 不能够使用的,例如 OC 中的预处理指令,即宏定义不可使用,虽然在目前4.2版本下,已经开始支持了少量的宏,如
#if DEBUG
#else
#endif
这种简单的预处理指令。Swift 中推荐使用常量定义,定义一些全局的常量实例、全局方法来充当 宏 的作用。
我们直到,Swift 中的一些自定义基类可以是不继承自 NSObject,这是 OC 调用这类的的时刻,就需要使用关键自 @objc 来标记,这样就可以正常使用来。
Swift中还有很多小细节部分,待大家在进一步学习过程中慢慢体会。
b. Objc 调用 Swift
由于国内大部分还都是 OC 编程环境,所以通常是先学习 OC 下调用 Swift。接下来我演示以下 OC 下配置桥接文件,以及 Objc 和 Swift 的相互调用。
当我们在项目中第一次添加不同语言的文件时,Xcode就会询问你是否创建桥接文件,你只需要点击”YES”,Xcode就可以帮你完成桥接配置(注意:第二次不会提示你,即使你删除来桥接文件)。
这份桥接文件是 Swift 调用 OC 文件的时,导入 OC 头文件使用的。在桥接文件中你可看到以下内容。
// Use this file to import your target's public headers that you would like to expose to Swift.
当然你也可以手动创建桥接文件,自己配置环境。
我们可以创建”项目名称-Bridging-Header”一个 .h 文件作为桥接文件,然后为项目配置此文件的路径。
此文件是存放 Swift 使用的 OC 头文件,此小节先不管它。
在 OC 调用 Swift 情况下,是通过Swift生成的一个头文件实现的,这个头文件是编译器自动完成的,它会将你在项目是到的 Swift 文件自动映射称 OC 语法,其他并不需要开发关注,该文件名称为 “项目名称-Swift”,你可以在 Build Settings 里搜索 Swift 可以看到:
这里还可以配置其他 Swift 的选项,如语言版本等。
接下来我们创建一个名为 “AViewController.swift” 的控制器,我们现在要在 OC 文件使用到该文件,首先,我们导入”项目名称-Swift.h”的文件,不会提示,需要你手动写入(可以按住Command点击头文件查看)。
在 OC 的 “ViewController.h” 文件中,我们进行跳转控制器,这个控制器的使用和使用 OC的类没有任何却别,系统的”项目名称-Swift.h”文件已经帮我完成了映射。
#import "ViewController.h"
#import "TestDemo-Swift.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"OC页面";
self.view.backgroundColor = [UIColor whiteColor];
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
AViewController *ctrl = [AViewController new];
[self.navigationController pushViewController:ctrl animated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
c. Swift 调用 Objc
前面提到了 “TestDemo-Bridging-Header.h” 文件,这个文件中存储的是用于供给 Swift 使用的 OC 头文件。
我们将 OC 控制器文件 “ViewController.h” 导入该文件,这样我们在 Swift 文件中就可以使用该文件。
import UIKit
class AViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Swift页面";
self.view.backgroundColor = UIColor.red
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let ctrl = ViewController()
self.navigationController?.pushViewController(ctrl, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWa