11. Swift 与OC互相调用.png

在 Swift 项目中调用 OC 的 API

  1. 创建 OC 类时,Xcode 会提醒是否自动添加桥接文件。文件名为 {TargetName}-Bridging-Header.h

swift-objc-bridge.png

  1. 编写 OC 的 API

objc-class.png

  1. Swift 调用 OC 的 API

swift-call-objc.png

  1. 同样可以手动添加桥接文件,需要项目配置中指定好桥接文件的路径

image.png

在 OC 项目中调用 Swift 的 API

  1. 创建 Swift 类时,Xcode 会提醒是否自动添加桥接文件。文件名为 {TargetName}-Bridging-Header.h

objc-swift-bridge.png

  1. 编写 Swift 的 API

只有继承 NSObject 的类才能被 OC 访问,另外给需要给 OC 使用的属性和方法添加 @objc 特性声明
image.png

  1. OC 调用 Swift 的 API

oc-call-swift.png

  1. 上面我们通过导入 oc_demo-Swift.h 文件,从而引用 Swift 的 API

这个文件是项目隐式创建的,你也可以对它重命名
edit-header.png

Swift 调用 OC 的注意事项

在 Swift 的代码中,若使用 OC 的语法特性,或提供给 OC 调用,那么一般需要加上 @objc 来修饰。

  • 提供给 OC 调用的属性和方法都必须显式添加 @objc

若希望类中所有的属性和方法都支持被 OC 调用,那么可以给类添加 @ objcMembers 声明

  • 在 Swift 协议中给方法添加可选特性 optional,这时需要添加 @objc
  1. @objc protocol MyProtocol {
  2. @objc optional func method1()
  3. @objc func method2()
  4. }
  5. class MyClass: MyProtocol {
  6. func method2() {
  7. }
  8. }
  • 给 UIButton 的实例添加点击事件时,通过 #selector 指定按钮点击的响应方法,该方法需要添加 @objc
  1. import UIKit
  2. class ViewController: UIViewController {
  3. override func viewDidLoad() {
  4. super.viewDidLoad()
  5. let button = UIButton(frame: CGRect(x: 20, y: 20, width: 100, height: 40))
  6. button.setTitle("Login", for: .normal)
  7. button.addTarget(self, action: #selector(onPress(button:)), for: .touchUpInside)
  8. self.view.addSubview(button)
  9. }
  10. @objc func onPress(button: UIButton) {
  11. print(button.currentTitle!) // "Login"
  12. }
  13. }
  • 将 Swift 整型关联值类型的枚举提供给 OC 调用,枚举成员的名词将有所变化
  1. @objc enum MyEnum: Int {
  2. case one = 1
  3. case two = 2
  4. }
  1. MyEnum e = MyEnumOne;
  • @objc 可以对类名进行重命名
  1. @objc(GFUser)
  2. class User: NSObject {
  3. }
  • @objc 可以对方法进行重命名,与 OC 中的 @selector 类似
  1. @objc(display:)
  2. func show(text: String) {
  3. }
  • @objc 可以接受参数,比如对 get 方法进行重命名
  1. @objc var fullName: String {
  2. @objc(getFullName) get {
  3. return "\(firstName) \(secondName)"
  4. }
  5. }
  • @nonobjc 可以废除一个隐式 objc 特性,使其在 Objective-C 代码中不可用