Swift和OC混编-1

现在的框架还是OC的比较多,虽然大部分都支持了Swift一旦遇到只支持OC的,还是需要用Swift调用OC,相反如果遇到一个OC的老模块不能使用了,那么编写一个新的Swift模块,也同时需要OC调用Swift

Swift调用OC

在Swift项目里面创建OC会提示需不需要生成桥接文件,一般是默认生成

会多一个targetname-Bridging-Header.h这样的一个桥接文件

*****如果不小心点到了Don‘t Create也没事(正常情况是默认生成不用手动去弄)

1.创建一个header.h,名称就是项目名-Bridging-Header.h比如我这个项目叫test,那么就是test-Bridging-Header.h

2.在building setting里面添加这个文件的路径 

3.在头文件里面写入想要的.h比如,要用Person.h就#import "Person.h"

@interface Person : NSObject
@property (nonatomic,strong) NSString *name;
@property (nonatomic,assign) int age;
@end

创建一个Person类,定义一个name属性,一个age属性

然后就可以在main.swift里面初始化调用了

var p = Person()
print(p.name)   //空字符串
print(p.age)   //0

可以看到默认的混编,Swift调用OC的类,会默认生成值,比如Int会默认为0,name会默认为空字符串

.h写上

-(instancetype)initWithName:(NSString *)name age:(int)age;

.m写上

-(instancetype)initWithName:(NSString *)name age:(int)age
{
    if (self = [super init]) {
        self.name = name;
        self.age = age;
    }
    return self;
}
var p = Person(name: "yk", age: 120)

就能正常的初始化了,值得注意的是,这里的Int是Int32而不是64

如果把初始化改成返回nil

-(instancetype)initWithName:(NSString *)name age:(int)age
{
//    if (self = [super init]) {
//        self.name = name;
//        self.age = age;
//    }
    return nil;
}

那么不管怎么赋值都不会有反应了

var p = Person(name: "yk", age: 120)
print(p.name)   //空字符串
print(p.age)   //0
p.name = "yk"
p.age = 10
print(p.name)   //空字符串
print(p.age)   //0

调用函数也不会有反应,所以看起来很像是底层做了个可选项操作,只是也不完全一样

函数冲突和类名冲突

如果函数和类名冲突,优先调用Swift自带的函数和类

假如有这么个场景,OC是第三方库,函数名不能改,Swift也不能修改,但又必须调用OC的函数

Swift 的函数是:

func sum(_ a:Int,_ b:Int) -> Int {
    a - b
}

OC的函数是:

int sum(int a,int b)
{
    return a + b;
}

这两个函数调用方式一样,系统会默认调用Swift的函数

@_silgen_name("sum")
func newSum(_ a:Int32,_ b:Int32) -> Int32
print(sum(10, 20))  // -10
print(newSum(10, 20))  //30

如果一定要调用OC的函数可以给OC函数重新命名名,注意这里的Int一定要转换为Int32

OC调用Swift

Swift的代码想要给OC用必须继承NSObject

@objcMembers class Person :NSObject {
    var name:String
    var age:Int
    init(name:String,age:Int) {
        self.name = name
        self.age = age
    }
}

比如这个Person类

然后还要导入头文件target-swift.h 其中target也是项目名,比如我得就是test-swift.h

********注意,一定要编译,不编译是不会刷新test-swift.h文件的

void ptr()
{
    Person *person = [[Person alloc] initWithName:@"yk" age:10];
    person.name = @"tk";
    person.age = 20;
    NSLog(@"%@,%d",person.name,person.age); //2021-05-21 19:08:03.396944+0800 test[1965:162612] tk,20
}

然后就可以正常的在OC里面调用Swift了

@objc关键字

用于展示名

@objc(YKPerson)
@objcMembers class Person :NSObject {
    var name:String
    var age:Int
    init(name:String,age:Int) {
        self.name = name
        self.age = age
    }
}
ptr()

比如为了迎合OC的口味,这里写了YKPerson

void ptr()
{
    YKPerson *person = [[YKPerson alloc] initWithName:@"yk" age:10];
    person.name = @"tk";
    person.age = 20;
    NSLog(@"%@,%d",person.name,person.age); //2021-05-21 19:08:03.396944+0800 test[1965:162612] tk,20
}

这里也得跟着改

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值