想必各位讀者也都知道在oc下的點語法就是調(diào)用getter和setter方法,所以通過重寫getter和setter方法可以在你給一個類的屬性賦值的時候做一些處理,好讓以后的操作更加方便,比如寫一個UIVIew的分類,然后往里面加一個x屬性
@property(nonatomic.assign)CGFloat x;
//雖然在分類里面不能添加屬性,但上面這句代碼就等價于
-(void)setX:(CGFloat)x;
-(CGFloat)x;
//再在.m文件里重寫getter和setter方法
-(void)setX:(CGFloat)x
{
CGFrame frame = self.frame;
frame.origin.x=x;
self.frame=frame;
}
-(CGFloat)x
{
return self.frame.origin.x;
}
/*這樣在引入頭文件后,設(shè)置一個控件的frame的時候就可以直接用點語法了,
因為控件的frame不可以直接給位置或大小賦值,只能重新賦一個frame給他
這樣在控件多并且為之有改變,不用約束的情況下會很方便*/
/*
但以上方法在swift中的使用差距就會有點大了,那么我就先說一下我對swift的setter和getter方法的理解吧,首先swift里面已經(jīng)沒有了.m和.h文件,這樣就不能通過@proerty來創(chuàng)建getter和setter方法了,雖然有set和get,不過它們不能給自己賦值,但可以通過它改變一些其它的值,總體來講就是功能更強(qiáng)大了,那么我就先舉個小例子
*/
//先實現(xiàn)和ocgeitter和setter一樣的效果
//首先swift里的變量和常量,變量是var常量是let因為要重寫,要重新賦值所以用var
//myd賦個空也可以""但不能什么也不寫,會報錯
var name = "myd" { /*這里是在賦值之前會調(diào)用,在這里面會有一個新屬性newValue,這個newValue就等價與之前oc里面的-(void)setX:(CGFloat)x;里面最后面的那個小x這樣你就可以處理新值了,并把他直接賦值給當(dāng)前屬性*/
willSet{
name = newValue
} //這里就是在賦完值以后,馬上就回進(jìn)入,并不是當(dāng)你需要取值的時候才會進(jìn)到這里,但是這里面的name已經(jīng)是改變以后的值了,所以當(dāng)你對這里面的name進(jìn)行一系列的操作時其實就和oc里面的重寫get方法是一樣的,只不過是直接改變屬性本身的值,但效果都是一樣的
didSet{
name = name + "hhhh"
} }
//這樣如果我們在給它賦值的時候就可以在willSet里面做很多操作,并且可以在didSet里面修改里面的值,來起到當(dāng)我們再次調(diào)用這個屬性的時候拿到的是修改后的值"mydhhhh"
以上是為了好理解而寫的,下面是官方文檔的解釋
屬性監(jiān)視器
屬性監(jiān)視器監(jiān)控和響應(yīng)屬性值的變化,每次屬性被設(shè)置值的時候都會調(diào)用屬性監(jiān)視器,甚至新的值和現(xiàn)在的值相同的時候也不例外。
可以為除了延遲存儲屬性之外的其他存儲屬性添加屬性監(jiān)視器,也可以通過重載屬性的方式為繼承的屬性(包括存儲屬性和計算屬性)添加屬性監(jiān)視器。屬性重載請參考繼承一章的重載。
注意:不需要為無法重載的計算屬性添加屬性監(jiān)視器,因為可以通過 setter 直接監(jiān)控和響應(yīng)值的變化。
可以為屬性添加如下的一個或全部監(jiān)視器:
willSet在設(shè)置新的值之前調(diào)用
didSet在新的值被設(shè)置之后立即調(diào)用
willSet監(jiān)視器會將新的屬性值作為固定參數(shù)傳入,在willSet的實現(xiàn)代碼中可以為這個參數(shù)指定一個名稱,如果不指定則參數(shù)仍然可用,這時使用默認(rèn)名稱newValue表示。
類似地,didSet監(jiān)視器會將舊的屬性值作為參數(shù)傳入,可以為該參數(shù)命名或者使用默認(rèn)參數(shù)名oldValue。
注意:willSet和didSet監(jiān)視器在屬性初始化過程中不會被調(diào)用,他們只會當(dāng)屬性的值在初始化之外的地方被設(shè)置時被調(diào)用。
這里是一個willSet和didSet的實際例子,其中定義了一個名為StepCounter的類,用來統(tǒng)計當(dāng)人步行時的總步數(shù),可以跟計步器或其他日常鍛煉的統(tǒng)計裝置的輸入數(shù)據(jù)配合使用。
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
println("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
println("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
StepCounter類定義了一個Int類型的屬性totalSteps,它是一個存儲屬性,包含willSet和didSet監(jiān)視器。
當(dāng)totalSteps設(shè)置新值的時候,它的willSet和didSet監(jiān)視器都會被調(diào)用,甚至當(dāng)新的值和現(xiàn)在的值完全相同也會調(diào)用。
例子中的willSet監(jiān)視器將表示新值的參數(shù)自定義為newTotalSteps,這個監(jiān)視器只是簡單的將新的值輸出。
didSet監(jiān)視器在totalSteps的值改變后被調(diào)用,它把新的值和舊的值進(jìn)行對比,如果總的步數(shù)增加了,就輸出一個消息表示增加了多少步。didSet沒有提供自定義名稱,所以默認(rèn)值oldValue表示舊值的參數(shù)名。
注意:如果在didSet監(jiān)視器里為屬性賦值,這個值會替換監(jiān)視器之前設(shè)置的值。