- 今天我在OC混编Swift的项目中使用代理(委托)设计模式传值的时候被一个小小的语法问题给绊了好长时候,本来撸代码撸的正嗨的时候,被这个小点给怼蒙了。特此写下此文警示后人😆。
1,具体场景
- 用Swift写了一个view,OC写的控制器拥有这个view的引用,展示view,然后Swift需要使用代理回传值给OC。
2,二话不说上代码
- 代理回传值一般需要这样几步:
- 定义协议
// 1,定义协议
protocol SwiftViewDelegate {
func removeSwiftView()
}
- 添加代理属性
// 2,添加代理属性
var delegate : SwiftViewDelegate?
- 调用代理方法 (以上三步是在需要代理的类中写的)
// 3,调用代理方法
self.delegate?.removeSwiftView()
- 设置代理
self.swiftView.delegate = self;
- 遵守协议
@interface ViewController ()<SwiftViewDelegate>
3,上面的这个套路在OC或者Swift中 完全没有问题。但是当把Swift的代理设置给OC的时候或者OC类遵守协议的时候就会报错
Property 'delegate' not found on object of type 'SwiftView *'
提示你找不到代理属性,可是已经在Swift中已经定义了啊
Cannot find protocol declaration for 'SwiftViewDelegate'
我擦,这是啥情况,我明明在Swift类中定义了协议并且在OC中导入了"XXX-Swift.h"头文件 怎么就找不到SwiftViewDelegate
4,什么原因呢
- 查找Swift3.0翻译文档 发现了这句话
“可选的协议要求只能用在标记 @objc 特性的协议中。
该特性表示协议将暴露给 Objective-C 代码,详情参见Using Swift with Cocoa and Objective-C(Swift 2.2)。即使你不打算和 Objective-C 有什么交互,如果你想要指定可选的协议要求,那么还是要为协议加上 @objc 特性。
还需要注意的是,标记 @objc 特性的协议只能被继承自 Objective-C 类的类或者 @objc 类采纳,其他类以及结构体和枚举均不能采纳这种协议。”
- 因为Swift中协议中的方法默认是必须实现的,OC中协议中的方法默认都是可选实现的。Swift中定义的协议默认是不暴漏给OC的,如果想在OC中使用协议,需要在定义协议的时候 在前面加上@objc 告诉OC
- 协议加上@objc 后 协议中定义的方法都变为可选实现的了。
5,正确姿势
@objc protocol SwiftViewDelegate {
func removeSwiftView()
}
6,demo源码
https://github.com/JTWang4778/DelegateInOCSwfit.git
网友评论