OC混编Swift中代理设计模式的小坑

  • 今天我在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

7,对于@objc的详细作用请参考文章

http://www.cnblogs.com/Rinpe/p/5466470.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容