美文网首页Swift DeveloperSwift开发者iOS Developer
OC混编Swift中代理设计模式的小坑

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

作者: 远辰jt | 来源:发表于2017-05-17 23:40 被阅读87次
    • 今天我在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

    相关文章

      网友评论

      本文标题:OC混编Swift中代理设计模式的小坑

      本文链接:https://www.haomeiwen.com/subject/czsjxxtx.html