Swift和OC混编中的一些注意事项及问题
混编头文件的导入
Swift引用OC
在桥接文件中导入OC头文件即可 #import “xxx.h”
注意事项:
-
OC中的类直接或间接继承制NSObject
-
暴露给Swift的所有属性和函数前面都要加上 @objc
OC引用Swift
导入头文件 #import "项目名-Swift.h"
(此文件由系统生成,如果用户自定义可以再 build settings 中的 packaging -> Product Modular Name中找到)
oc类在使用swift类时,该swift类必须继承于oc类
swift中没有宏,可以使用全局常量、全局函数代替部分宏
swift中是不能使用宏定义语法,但是因为命名空间的缘故,在其中,我们将原本oc中不需要接受参数的宏,定义成let常量或枚举,将需要接受参数的宏定义成函数。 ⚠️横屏后kScreenHeight及kScreenWidth是不会变化的,因为是常量,只会赋值一次。OC中则会实时变化,因为不是赋值,是宏替换。 ⚠️ 这里定义的常量oc中并不能使用,可以定义一个类,然后将所有的全局变量和常量改成这个类的属性。
如oc的宏:
1 |
|
在swift中定义为全局常量:
1 |
|
swift枚举类型在oc中使用
如果需要在oc类中使用时只能使用带@objc的枚举,带@objc的枚举必须时Int类型,否则会报错。
1 |
|
只有像上面定义的Swift枚举才能在oc类中使用。
swift中使用oc的NS_OPTIONS类型枚举
swift中没有“ | ”,如,下面写法是错误的 |
1 |
|
可以直接写成
1 |
|
注:swift中与NS_OPTIONS相似的是struck实现 OptionSet 协议。
oc使用swift定义的协议
如果要在oc中使用swift定义的协议,则需要加上@objc,且如果是不必实现的函数,函数前要加上 @objc optional。
1 |
|
其他swift中有而oc中没有的
- 元组:对于oc可能用到的:方法,返回不能是元组,参数能不能是元组。属性不能是元组。
- 范型(Generics)范型
- Swift 中定义的结构体(Structures defined in Swift)不能在oc中使用,OC中必须继承NSObject(OC不能使用Swift结构体)
- Swift 中定义的高阶函数(比如filter, map等)
- Swift 中定义的全局变量(Global variables defined in Swift)
- Swift 中定义的类型别名(Typealiases defined in Swift)
- Swift风格可变参数(Swift-style variadics)
- 嵌套类型(Nested types)
- 柯里化函数(Curried functions)
这里稍微解释一下柯里化在计算机科学中,柯里化(Currying),又译为卡瑞化或加里化,是把接收多个参数的函数变换成接收一个单一参数(最初函数的第一个参数)的函数,并返回接受剩余的参数而且返回结果的新函数的技术, 简而言之其实质就是闭包的概念,如下两个函数
1 |
|
调用方式如下:
1 |
|
常见问题:
swift类可以继承oc类,oc类不能继承swift类
1. Swift通过cocoapods导入OC的三方框架, 在Swift中找不到这个类
-
1.Target -> Search paths -> User Header Search Paths
-
2.新增一个值
${SRCROOT}
, 并且选择Recursive
(意思是在根目录递归查找)
2.在OC引用Swift文件时, 导入 项目名-Swift.h
文件时, 报找不到文件的错
原因: 桥接文件的路径没有配置正确:
-
1.
Build Settings
-> 搜索Bridging
->Objective-C Bridging Header
-> 配置路径 -
2.配置路径的方法:
项目名/桥接文件的名称
(如果桥接文件有多层物理目录, 就是 项目名/物理目录/桥接文件的名称)