Swift OC 混编
Swift接入
OC use Swift method
- 将Swift导入OC
#import "ProductModuleName-Swift.h"
ProductModuleName-Swift.h文件中包含了.swift文件中的声明等。
- Include Swift Classes Using Forward Declarations
@class MySwiftClass; // in .h
#import "ProductModuleName-Swift.h" // in .m
-
使用
@objc暴露函数给OC 或者 使用@objcMembers暴露整个类给OC -
如果是在开发一个
library, 大概率CocoaPods已经为你生成了ProductModuleName-Swift.h文件, 你使用的时候手动import这个文件:#import <MyOpenSDK/MyOpen-Swift.h>
Swift use OC method
- 创建桥接头文件 首次添加Swift时会提示增加
bridging header - 转化宏定义
Swift只支持简单的数值宏定义,函数式等复杂的宏定义不支持,需要一个中间类转化一下,创建一个中间类 KBSwiftConstant.swift, 如下:
+ (CGFloat)ScreenWidth{
return SCREEN_WIDTH;
}
Swift中不建议使用宏,简单的可以使用
let,复杂的宏可以使用静态函数,内联函数,generics等。
Attention
- bridging header分模块
- class delete 关键字
- 没有
nullable修饰符的OC属性会默认转化为swift的隐式可选型(!),系统不会提示加?解包,解包时需注意,如果属性值可能为空,需要在属性末尾加?,例如:self.property?.property - 初始化方法
- 初始化函数需要使每个属性都有初始值,optional类型自动初始值为nil
- 不自动集成父类构造函数,原因为子类集成父类的构造函数容易导致初始化不全面,即不符合条件(1)
- 执行顺序规范
- convinence init
- Swift不识别OC自动生成的
setter方法,直接对属性赋值,即可调用到setter方法 - 单例, 仅在定义全局变量时将其构造器标志为
private,即可自动使用 dispatch_once 进行初始化,保证原子性
先给自己的属性赋值再super.init(),
- 等于init方法一进来就已经有self了
- 这也是为什么不需要返self的原因
class childClass: fatherClass {
var childProperty:Any?
init(childProperty:Any?){
self.childProperty = childProperty
super.init()
self.fatherProperty = ...
}
}
自定义初始化参数,需要符合以下原则:
convinence init函数中需调用当前类中其他初始化函数designated init函数中需调用父类的designated init函数convinence init需要最终调用到designated init函数
class MyManager {
// 全局变量
static let shared = MyManager(string: someString)
let string: String
private init(string: String) {
self.string = string
}
}
// 使用方法:
MyManager.shared.method()
Enums
OC只认Swift里定义的Int类型枚举, 并且扩展的属性, 方法, 及associate data等都无法读取(定义的时候就报错了). 并且需要标识上@objc
case login(username: String, password: String)
// 更简单的(但就丧失了可读性):
case login(String, String)
这种枚举, 在取数值的时候以下两种写法都可以:
case let .login(username, password):
case .login(username: let username, password: let password):
// 没有名字的, 就要在switch的时候自行解包:
// 1. 比每一个形参都加let要简洁很多, 但比直接把let提取到最外面的写法是一样的
// 2. 在case的时候自定义形参名, 意思是编辑的时候是没有智能提示的(反而会瞎提示)
case let (username, password):
case .login(let username, let password):
而OC里的枚举, 会根据写法在Swift里映射成不同的类型, 参考这篇笔记混编中的枚举