Swift与objective-c混编整理

swift项目中混编 objective-c

1、新建一个 swift项目工程
2、创建一个 cocoa touch class 类, 语言选择 objective-c
IMAGE
点击next然后点 create之后会弹出如下弹窗
IMAGE
点击 Create Bridging Header创建桥接头文件。此时的项目工程文件文件如下:
IMAGE
3、检查build Settings -> swift compiler-code Generation 中的objective-c Bridging Header 设置是否为 前面创建的桥接头文件路径。在步骤 2中创建的头文件 xcode 会自动生成对应的配置。如果不小心将桥接文件删除了,然后自己手动建立一个新的桥接头文件记得检查此处配置
IMAGE
同时检查下图的配置:
IMAGE
4、我们在Person类里面添加如下代码

//Person.h文件
- (instancetype) initWithName:(NSString *)name age:(NSInteger)age;
// Person.m文件
#import "Person.h"
@interface Person()
@property(nonatomic,copy)NSString * name;
@property(nonatomic,assign)NSInteger age;
@end
@implementation Person

- (instancetype) initWithName:(NSString *)name age:(NSInteger)age{

    self = [super init];
    if (self) {

        self.name = name;
        self.age = age;
    }

    return self;
}

- (NSString *)description {

    return [NSString stringWithFormat:@"name = %@ age = %ld",self.name,self.age];
}
@end

5、然后在 swift-oc-Bridging-Header.h文件中 导入 Person.h文件

#import "Person.h"

6、使用

      let p:Person = Person.init(name: "小明", age: 18);
      print(p.description);

控制台输出:
IAMGE

存在的坑

1、swift是一门类型安全的语言,objective-c不是类型安全的。所以在OC的代码中一定要注意oc端代类的成员遍历是否能够为空, 在oc端声明属性的时候最好对象类型的属性最好能够加上nullable或者nonnull两个关键词修饰。如果不加这两个关键词修饰,在swift中默认 oc端的变量都是 nonnull。如下图:
IMAGE
那么在swift中使用该变量的时候,该变量没有被初始化或者被置成nil那么程序就会crash
如下示例:
头文件中所有的变量没有添加 nullable或者nonnull修饰
IMAGE
Person.m文件中不给 name属性初始化
IMAGE
在swift中使用name属性就会闪退
IMAGE

2、swift使用oc的第三方库有风险。

obejective-c 文件中使用 swift类

首先要导入一个 xxx-Swift.h头文件, 这个文件不用我们手动生成, 路径在

/Library/Developer/Xcode/DerivedData/xxx-doxrfnudrqzmbfgxpgidrxdpwwiw/Build/Intermediates.noindex/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/xxx-Swift.h

如果不想去路径下面查看,可以在下图的位置中查看
IMAGE
* xxx 代表项目名称,如果项目中有--_替换 如:swift-oc替换成swift_oc

坑:不要在oc的.h文件中导入 。如果要用swift中的类则需要在.h文件中 @class需要使用的类。 然后在.m文件中导入 xxx-Swift.h文件 示例如下:
IMAGE

IMAGE

到这里我们在oc中使用swift类的话会发现 swift中的所有的属性和公开的方法在oc端都不能调用。点进 xxx-swift.h文件发现
IMAGE
头文件里面只有swift类的初始化方法。
解决方案:swift类所有需要暴露给 oc端的属性和方法 都要以@objc修饰。如下示例:
IMAGE

能够让oc使用的swift类是要具备一定条件的:
* Swift4.0如果要暴露接口和属性给OC的话,需要在其前加@objc关键字
* 每个Target下的Bulid Settings中的Defines Modules设置为YES
* Swift类必须继承 NSObject类或其子类
* 对于自定义的类而言,Objective-C的类,不能继承自Swift的类,即要混编的OC类不能是Swift类的子类。反过来,需要混编的Swift类可以继承自OC的类
* Swift中有许多OC没有的特性,比如,Swift有元组、为一等公民的函数、还有特有的枚举类型。所以,要使用的混编文件要注意Swift独有属性问题。
* 如Swift文件要使用OC中定义的宏,只能使用常量简单宏文件。

使用framework

使用第三方Framework
设置: target–>build setting –>Packaging –>Defines Module为 “Yes”;
然后,配置文件Target -> Build Phases -> Link Binary,添加要导入的Framework;
最后,还是要配置桥接文件,比如要使用 abc-lib.framework库中的 abc.h 就要这样配置:#import”abc-lib/abc.h”;

猜你喜欢

转载自blog.csdn.net/philm_ios/article/details/81117670