美文网首页
Swift OC互调

Swift OC互调

作者: 曹来东 | 来源:发表于2019-08-06 18:00 被阅读0次
  • 新建一个桥接头文件,文件名格式默认为:{targetName}-Bridging-Header.h
  • {targetName}-Bridging-Header.h文件中#import OC需要暴露给Swift的内容 #import "LDPerson"
    image.png
    image.png
    image.png
let p = LDPerson(age: 10, name: "Jack")
 p.age = 18
 p.name = "Rose"
 p.run()//Person - Run 对象方法
 p.eat("Apple", other: "Other")//-eat Apple Other 对象方法
 LDPerson.run()//Person + Run 类方法
 LDPerson.eat("Apple", other: "Other")//+eat Apple Other 类方法
 print(sum(10, 20))// 30

@_silgen_name

  • 如果C语言暴露给Swift的函数名跟Swift中的其他函数名冲突了,可以在Swift中使用@_silgen_name修改C函数名
  • LDPerson中有个同名为sumC语言函数
    image.png
import UIKit
@_silgen_name("sum") func swift_sum(_ v1: Int32, _ v2: Int32) -> Int32
//Swift函数
func sum(_ a: Int, _ b: Int) -> Int { a - b }

class HomeViewController: UIViewController {
    override func viewDidLoad() {
      print(sum(10, 20))
      print(swift_sum(10, 20))
    
    } 
}

OC调用Swift

  • Xcode已经默认生成一个用于OC调用Swift的头文件,文件格式为:{targetName}-Swift.h
    image.png
  • Swift暴露给OC的类最终继承自NSObject
  • 使用@objc修饰需要暴露给OC的成员
  • 使用@objcMembers修饰类
  • 代表默认所有成员都会暴露给OC(包括扩展中定义的成员)
  • 最终是否成功暴露,还需要考虑成员自身的访问级别
import UIKit

@objcMembers class LDCar: NSObject {

    var price: Double
    var band: String
    init(price: Double, band: String) {
        self.price = price
        self.band = band
    }
    func run() {
        print(price, band, "run")
    }
    static func run() { print("LDCar run") }
 
}

extension LDCar {
    func test() {
        print(price, band, "test")
    }
}
  • Xcode会根据Swift代码生成对应的OC声明,写入{targetName}-Swift.h文件中.可以通过#import "SwiftProject-Swift.h"头文件查看文件内容
SWIFT_CLASS("_TtC12SwiftProject5LDCar")
@interface LDCar : NSObject
@property (nonatomic) double price;
@property (nonatomic, copy) NSString * _Nonnull band;
- (nonnull instancetype)initWithPrice:(double)price band:(NSString * _Nonnull)band OBJC_DESIGNATED_INITIALIZER;
- (void)run;
+ (void)run;
- (nonnull instancetype)init SWIFT_UNAVAILABLE;
+ (nonnull instancetype)new SWIFT_UNAVAILABLE_MSG("-init is unavailable");
@end


@interface LDCar (SWIFT_EXTENSION(SwiftProject))
- (void)test;
@end

OC调用Swift-OC代码

image.png
int sum (int a, int b){
    LDCar* car = [[LDCar alloc] initWithPrice:10.5 band:@"BWM"];
    car.band = @"Bently";
    car.price = 108.3;
    [car run];//108.3  Bently run  
    [car test];//108.3  Bently test  分类方法
    return a + b;
}

import UIKit
//给LDPerson中的sum函数重命名,因为OC文件中的sum函数和Swift中的sum函数同名,
//调用会引起二义性
@_silgen_name("sum") func swift_sum(_ v1: Int32, _ v2: Int32) -> Int32
//Swift函数
func sum(_ a: Int, _ b: Int) -> Int { a - b }

class HomeViewController: UIViewController {
    override func viewDidLoad() {
      
      print(swift_sum(10, 20))
    
    } 
}

-@objc

  • 可以通过@objc重命名Swift暴露给OC的符号名(类名 属性名 函数名等)
import UIKit
@objc(LDRenameCar)
@objcMembers class LDCar: NSObject {

    var price: Double
    @objc(name)
    var band: String
    init(price: Double, band: String) {
        self.price = price
        self.band = band
    }
    @objc(drive)
    func run() {
        print(price, band, "run")
    }
    static func run() { print("LDCar run") }
 
}

extension LDCar {
    //error:
    //'@objc' method name provides names for 2 arguments, but method has 0 parameters
    @objc(exec:v2:)
    func test() {
        print(price, band, "test")
    }
}

//重命名后 属性 方法名改变
int sum (int a, int b){
    LDRenameCar* car = [[LDRenameCar alloc] initWithPrice:10.5 band:@"BWM"];
    car.name = @"Bently";
    car.price = 108.3;
    [car drive];//108.3  Bently run
    [car exec];//108.3  Bently test  分类方法
    return a + b;
}

选择器(Selector)

  • Swift中依然可以使用选择器,使用#selector(name)定义一个选择器
  • 必须是被@objcMembers@objc修饰的方法才可以定义选择器
import UIKit
@objcMembers class LDCar: NSObject {
        func test1(v1: Int) {
            print("test1")
        }

        func test2(v1: Int,v2: Int) {
            print("test2(v1:v2)")
        }
        func test2(_ v1: Double,_ v2: Double) {
            print("test2(_:_)")
        }
    
    func run() {
        perform(#selector(test1))
        perform(#selector(test1(v1:)))
        perform(#selector(test2(v1:v2:)))
        perform(#selector(test2(_:_:)))
        perform(#selector(test2 as (Double, Double) -> Void))
    }
}

int sum (int a, int b){
    LDCar * car = [[LDCar alloc] init];
    [car run];
    
    return a + b;
}

import UIKit
//给LDPerson中的sum函数重命名,因为OC文件中的sum函数和Swift中的sum函数同名,
//调用会引起二义性
@_silgen_name("sum") func swift_sum(_ v1: Int32, _ v2: Int32) -> Int32
//Swift函数
func sum(_ a: Int, _ b: Int) -> Int { a - b }

class HomeViewController: UIViewController {
    override func viewDidLoad() {
      
      print(swift_sum(10, 20))
    
    } 
}

相关文章

网友评论

      本文标题:Swift OC互调

      本文链接:https://www.haomeiwen.com/subject/lgnidctx.html