- 今天我在OC混編Swift的項(xiàng)目中使用代理(委托)設(shè)計(jì)模式傳值的時(shí)候被一個(gè)小小的語法問題給絆了好長時(shí)候无蜂,本來擼代碼擼的正嗨的時(shí)候喇完,被這個(gè)小點(diǎn)給懟蒙了。特此寫下此文警示后人??蹬耘。
1,具體場(chǎng)景
- 用Swift寫了一個(gè)view芝雪,OC寫的控制器擁有這個(gè)view的引用,展示view综苔,然后Swift需要使用代理回傳值給OC惩系。
2,二話不說上代碼
- 代理回傳值一般需要這樣幾步:
- 定義協(xié)議
// 1如筛,定義協(xié)議
protocol SwiftViewDelegate {
func removeSwiftView()
}
- 添加代理屬性
// 2堡牡,添加代理屬性
var delegate : SwiftViewDelegate?
- 調(diào)用代理方法 (以上三步是在需要代理的類中寫的)
// 3,調(diào)用代理方法
self.delegate?.removeSwiftView()
- 設(shè)置代理
self.swiftView.delegate = self;
- 遵守協(xié)議
@interface ViewController ()<SwiftViewDelegate>
3杨刨,上面的這個(gè)套路在OC或者Swift中 完全沒有問題晤柄。但是當(dāng)把Swift的代理設(shè)置給OC的時(shí)候或者OC類遵守協(xié)議的時(shí)候就會(huì)報(bào)錯(cuò)
Property 'delegate' not found on object of type 'SwiftView *'
提示你找不到代理屬性,可是已經(jīng)在Swift中已經(jīng)定義了啊
Cannot find protocol declaration for 'SwiftViewDelegate'
我擦妖胀,這是啥情況芥颈,我明明在Swift類中定義了協(xié)議并且在OC中導(dǎo)入了"XXX-Swift.h"頭文件 怎么就找不到SwiftViewDelegate
4,什么原因呢
- 查找Swift3.0翻譯文檔 發(fā)現(xiàn)了這句話
“可選的協(xié)議要求只能用在標(biāo)記 @objc 特性的協(xié)議中。
該特性表示協(xié)議將暴露給 Objective-C 代碼赚抡,詳情參見Using Swift with Cocoa and Objective-C(Swift 2.2)爬坑。即使你不打算和 Objective-C 有什么交互,如果你想要指定可選的協(xié)議要求怕品,那么還是要為協(xié)議加上 @objc 特性妇垢。
還需要注意的是,標(biāo)記 @objc 特性的協(xié)議只能被繼承自 Objective-C 類的類或者 @objc 類采納肉康,其他類以及結(jié)構(gòu)體和枚舉均不能采納這種協(xié)議闯估。”
- 因?yàn)镾wift中協(xié)議中的方法默認(rèn)是必須實(shí)現(xiàn)的吼和,OC中協(xié)議中的方法默認(rèn)都是可選實(shí)現(xiàn)的涨薪。Swift中定義的協(xié)議默認(rèn)是不暴漏給OC的,如果想在OC中使用協(xié)議,需要在定義協(xié)議的時(shí)候 在前面加上@objc 告訴OC
- 協(xié)議加上@objc 后 協(xié)議中定義的方法都變?yōu)榭蛇x實(shí)現(xiàn)的了炫乓。
5,正確姿勢(shì)
@objc protocol SwiftViewDelegate {
func removeSwiftView()
}
6,demo源碼
https://github.com/JTWang4778/DelegateInOCSwfit.git