在iOS開(kāi)發(fā)中,代理模式(protocol - delegate)是界面之間數(shù)據(jù)傳遞最為常見(jiàn)的一個(gè)設(shè)計(jì)模式
在Cocoa框架中也有大量使用,可以說(shuō)是作為iOS開(kāi)發(fā)者必備技能。
在我們OC開(kāi)發(fā)時(shí)候使用delegate一般會(huì)把修飾符寫(xiě)成weak,這樣在這個(gè)delegate實(shí)際的對(duì)象被釋放的時(shí)候,會(huì)被置為nil,避免內(nèi)存泄露。代碼大致如下:
@property (nonatomic, weak) id<MGIndexAdReusableViewDelegate> delegate;
那么一般寫(xiě)過(guò)OC的童鞋去寫(xiě)swift,也會(huì)照本宣科,也設(shè)置為weak,沒(méi)有錯(cuò),但是事實(shí)情況會(huì)是怎樣呢 ?看如下代碼:
protocol TestDelegate {
func testMethod()
}
class TestClass {
weak var delegate: TestDelegate?
}
class ViewController: UIViewController, TestDelegate {
var testInstance: TestClass!
override func viewDidLoad() {
super.viewDidLoad()
testInstance = TestClass()
testInstance.delegate = self // error: 'weak' cannot be applied to non-class type 'TestDelegate'
}
func testMethod {
print("Test!")
}
}
上面注釋部分是報(bào)錯(cuò)信息,為什么呢 ?
這是因?yàn)閟wift中的protocol是可以被除class類型以外的struct type和enum type所遵守的,那么原因不言而喻了。struct type和enum type,他們本身是不通過(guò)引用計(jì)數(shù)來(lái)管理內(nèi)存的,所以也就不能使用weak來(lái)修飾,那么怎么辦呢 ?
方法有兩種
1.將protocol聲明為Objective - C的,通過(guò)在protocol前面加@objc關(guān)鍵字來(lái)實(shí)現(xiàn),這樣就只能由class來(lái)遵守了,代碼大致如下:
@objc protocol TestDelegate {
func testMethod()
}
2.在protocol的聲明后面加上class,這樣可以為編譯器顯式的指名這個(gè)protocol只能由class來(lái)遵守,代碼大致如下:
// 更推薦這種方式,易于理解,更能表現(xiàn)出問(wèn)題的實(shí)質(zhì)
protocol TestDelegate: class {
func testMethod()
}