Swift与Objective-C互相调用(总结)
公司正式使用swift语言开发项目已经一年多, 现在总结一下swift和OC互相调用的经验
swift调用OC
- Swift调用OC类,必须要有桥接文件,且在桥接文件中 import OC类的.h文件。
1. 创建 "工程名称"-Bridging-Header.h
文件
- 创建新的工程时会自动提示创建桥接文件SwiftTestProject(工程名称)-Bridging-Header.h, 这个文件是swift调用OC所必须的.
创建桥接文件
-
如果新建工程没有勾选创建
image.png-Bridging - Header.h
文件, 则需要手动创建一个"工程名称"-Bridging-Header.h
文件,
创建一个Header File文件,一般命名为“项目名-Bridging-header”
,内容清空
-
然后在工程中设置:
image.pngTARGET -> Build Settings -> Objective-C Bridging Header
填充好你的文件名称:"工程名称"-Bridging-Header.h
-
找到工程文件下的
image.pngTARGETS --> Build settings
中搜索Defines Module
设置为YES
2. 引入OC的.h头文件 就能在swift项目中调用相对于的OC类了.
image.pngoc调用swift
1. 工程配置
找到工程文件下的TARGETS -->Build settings
中搜索 Product Module Name
设置为工程名,这时工程会自动创建一个"项目名"-Swift.h
的文件,该项目中为“SwiftTestProject-Swift.h”,这个文件用于oc调用swift文件, 默认不展示的.
2. 引入 "项目名"-Swift.h
文件
在OC文件里面里面#import "项目名称-Swift.h"
, 注意这个文件没有提示,要手动打出来,然后就能在OC类里面使用swift的类了.
注意和总结
- oc引用swift文件要引用“项目名-Swift.h”文件, 需要手动敲, 没提示的,swift引用oc文件要创建桥接文件,桥接文件中引用oc的.h文件
-
注意OC调用swift, swfit中的类需要注意的地方,
image.png
- 特别注意
OC调用Swift中的Class类
- 这个类必须是继承
NSObjec
或者NSObjec
的子类 - Class前面要加
@objcMembers
(这个关键字是让该类所有属性和方法加上@objc
),3.0之前是苹果自动帮你加上的,据说嫌弃打包会偏大一些,后面改成自己手动加。
例如:
@objcMembers class CustomServiceTool: NSObject {}
- 类中的协议、枚举、结构体这些东西的调用
- 协议:直接在前面加一个
@objc
@objc protocol CustomServiceToolDelegate: NSObjectProtocol {}
- 枚举:必须定义出
Int
类型,前面加@objc
才能调用(毕竟swift的枚举比OC强大太多)
@objc enum CPLineType: Int {
case schoolToHome = 0
case homeToSchool
case return
}
- 结构体:在oc中是不能调用struct里面的内容的,你想在类似class前面加个@objc的方法加在struct前面是不行的,那但是我们又想在oc中调用struct的属性,那怎么办呢?我们只能再建一个类,在类里写个方法来返回struct中的值
坑点:
-
每次在一个类前面加个
@objcMembers
的时候都需要重新编译一遍才能打出提示(混编期间,报错请不要怀疑自己的代码,大部分编译一下就没事了。。。) -
有种特殊的情况,比如我一个OC控制器中调用了swift写的view,然后其他用swift写的控制器需要调用OC控制器,这时候要是只是把OC控制器写到桥接文件中是会报错的。(这种就是混编项目比较变态的情况)------------解决办法:swift写的View用向前声明( @class BannerView);
-
swift中的一些类型是OC没有的,或者类型名字差不多但是类型完全不同
例如:
swift中的Int定义成可选类型的时候,这时候OC是调不了swift的Int类型,解决方式,定义普通Int型