Swift(十五)屬性

星空

計(jì)算屬性和存儲(chǔ)屬性

我們知道在OC中, 使用@ property聲明的實(shí)例變量, 都會(huì)自動(dòng)生成setter和getter方法, 但是在swift中, 屬性分為計(jì)算屬性和存儲(chǔ)屬性, 存儲(chǔ)屬性存儲(chǔ)常量或變量作為實(shí)例的一部分萄喳,計(jì)算屬性計(jì)算(而不是存儲(chǔ))一個(gè)值,就是setter和getter方法, 除存儲(chǔ)屬性外加派,類素标、結(jié)構(gòu)體和枚舉可以定義計(jì)算屬性蛆楞,計(jì)算屬性不直接存儲(chǔ)值,而是提供一個(gè) getter 來(lái)獲取值,一個(gè)可選的 setter 來(lái)間接設(shè)置其他屬性或變量的值。

延遲存儲(chǔ)屬性

延遲存儲(chǔ)屬性是指當(dāng)?shù)谝淮伪徽{(diào)用的時(shí)候才會(huì)計(jì)算其初始值的屬性。在屬性聲明前使用lazy(xcode8)不是@lazy來(lái)標(biāo)示一個(gè)延遲存儲(chǔ)屬性羹应。類似于OC中的懶加載

注意:必須將延遲存儲(chǔ)屬性聲明成變量(使用var關(guān)鍵字),因?yàn)閷傩缘闹翟趯?shí)例構(gòu)造完成之前可能無(wú)法得到(意思就是說(shuō), 延遲屬性, 不需要在創(chuàng)建實(shí)例時(shí)賦初始值)次屠。而常量(使用var)屬性在構(gòu)造過(guò)程完成之前必須要有初始值(如果你不給初始值, 編譯器會(huì)根據(jù)類型推斷, 自動(dòng)分配)园匹,因此無(wú)法聲明成延遲屬性。

class DataImporter { 
    /* 
    DataImporter 是一個(gè)將外部文件中的數(shù)據(jù)導(dǎo)入的類劫灶。 
    這個(gè)類的初始化會(huì)消耗不少時(shí)間裸违。 
    */ 
    var fileName = "data.txt" 
    // 這是提供數(shù)據(jù)導(dǎo)入功能 
} 
 
class DataManager { 
    lazy var importer = DataImporter()  //延遲屬性, 用到的時(shí)候才回去加載
    var data = String[]() 
    // 這是提供數(shù)據(jù)管理功能 
} 

計(jì)算屬性

//結(jié)構(gòu)體
struct Point { 
    var x = 0.0, y = 0.0 
} 
//結(jié)構(gòu)體
struct Size { 
    var width = 0.0, height = 0.0 
} 
//結(jié)構(gòu)體
struct Rect { 
    var origin = Point() 
    var size = Size() 
    var center: Point { 
//getter方法
    get { 
        let centerX = origin.x + (size.width / 2) 
        let centerY = origin.y + (size.height / 2) 
        return Point(x: centerX, y: centerY) 
    } 
//setter方法, newCenter為setter方法的參數(shù)
    set(newCenter) { 
        origin.x = newCenter.x - (size.width / 2) 
        origin.y = newCenter.y - (size.height / 2) 
    } 
    } 
} 
//聲明一個(gè)結(jié)構(gòu)體
var square = Rect(origin: Point(x: 0.0, y: 0.0), 
    size: Size(width: 10.0, height: 10.0)) 
let initialSquareCenter = square.center  //getter方法, 獲取center
square.center = Point(x: 15.0, y: 15.0)  //setter方法, 設(shè)置新的center
print("square.origin is now at (\\(square.origin.x), \\(square.origin.y))") 

只讀計(jì)算屬性

只有 getter 沒(méi)有 setter 的計(jì)算屬性就是只讀計(jì)算屬性。只讀計(jì)算屬性總是返回一個(gè)值本昏,可以通過(guò)點(diǎn)運(yùn)算符訪問(wèn)供汛,但不能設(shè)置新的值。(類比OC屬性修飾readonly)
注意:必須使用var關(guān)鍵字定義計(jì)算屬性涌穆,包括只讀計(jì)算屬性怔昨,因?yàn)樗麄兊闹挡皇枪潭ǖ摹et關(guān)鍵字只用來(lái)聲明常量屬性宿稀,表示初始化后再也無(wú)法修改的值趁舀。

struct Cuboid { 
    var width = 0.0, height = 0.0, depth = 0.0 
    var volume: Double { //只讀計(jì)算屬性的聲明可以去掉get關(guān)鍵字和花括號(hào):

    return width * height * depth 
    } 
} 
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0) 
print("the volume of fourByFiveByTwo is \\(fourByFiveByTwo.volume)") 

屬性監(jiān)視器

屬性監(jiān)視器監(jiān)控和響應(yīng)屬性值的變化,每次屬性被設(shè)置值的時(shí)候都會(huì)調(diào)用屬性監(jiān)視器祝沸,甚至新的值和現(xiàn)在的值相同的時(shí)候也不例外. (類似于KVO, 但是比KVO方便多了)
可以為屬性添加如下的一個(gè)或全部監(jiān)視器:

willSet在設(shè)置新的值之前調(diào)用
didSet在新的值被設(shè)置之后立即調(diào)用
willSet監(jiān)視器會(huì)將新的屬性值作為固定參數(shù)傳入矮烹,在willSet的實(shí)現(xiàn)代碼中可以為這個(gè)參數(shù)指定一個(gè)名稱,如果不指定則參數(shù)仍然可用罩锐,這時(shí)使用默認(rèn)名稱newValue表示奉狈。

類似地,didSet監(jiān)視器會(huì)將舊的屬性值作為參數(shù)傳入涩惑,可以為該參數(shù)命名或者使用默認(rèn)參數(shù)名oldValue仁期。

注意:willSet和didSet監(jiān)視器在屬性初始化過(guò)程中不會(huì)被調(diào)用,他們只會(huì)當(dāng)屬性的值在初始化之外的地方被設(shè)置時(shí)被調(diào)用境氢。

class StepCounter { 
    var totalSteps: Int = 0 { 
    willSet(newTotalSteps) {  //willSet監(jiān)視器將表示新值的參數(shù)自定義為newTotalSteps
        print("About to set totalSteps to \\(newTotalSteps)") 
    } 
    didSet { 
        if totalSteps > oldValue  {  //didSet沒(méi)有提供自定義名稱蟀拷,所以默認(rèn)值oldValue表示舊值的參數(shù)名碰纬。
            print("Added \\(totalSteps - oldValue) steps") 
//注意:如果在didSet監(jiān)視器里為屬性賦值萍聊,這個(gè)值會(huì)替換監(jiān)視器之前設(shè)置的值。
        } 
    } 
    } 
} 
let stepCounter = StepCounter() 
stepCounter.totalSteps = 200  //設(shè)置新值, 調(diào)用willSet
// About to set totalSteps to 200 
// Added 200 steps 
stepCounter.totalSteps = 360 
// About to set totalSteps to 360 
// 

類型屬性

實(shí)例的屬性屬于一個(gè)特定類型實(shí)例悦析,每次類型實(shí)例化后都擁有自己的一套屬性值寿桨,實(shí)例之間的屬性相互獨(dú)立。

也可以為類型本身定義屬性,不管類型有多少個(gè)實(shí)例亭螟,這些屬性都只有唯一一份挡鞍。這種屬性就是類型屬性。

類型屬性用于定義特定類型所有實(shí)例共享的數(shù)據(jù)预烙,比如所有實(shí)例都能用的一個(gè)常量(就像 C 語(yǔ)言中的靜態(tài)常量)墨微,或者所有實(shí)例都能訪問(wèn)的一個(gè)變量(就像 C 語(yǔ)言中的靜態(tài)變量)。

對(duì)于值類型(指結(jié)構(gòu)體和枚舉)可以定義存儲(chǔ)型和計(jì)算型類型屬性扁掸,對(duì)于類(class)則只能定義計(jì)算型類型屬性翘县。

值類型的存儲(chǔ)型類型屬性可以是變量或常量,計(jì)算型類型屬性跟實(shí)例的計(jì)算屬性一樣定義成變量屬性谴分。

注意:跟實(shí)例的存儲(chǔ)屬性不同锈麸,必須給存儲(chǔ)型類型屬性指定默認(rèn)值,因?yàn)轭愋捅旧頍o(wú)法在初始化過(guò)程中使用構(gòu)造器給類型屬性賦值牺蹄。

//結(jié)構(gòu)體
struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 10
        // 這里返回一個(gè) Int 值
    }
}
//枚舉
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        // 這里返回一個(gè) Int 值
        return 20
    }
}
//類
class SomeClass {
//這里在xcode8里, class改為static也可以(目前測(cè)試, 結(jié)果都是對(duì)的, 可能還有沒(méi)有考慮到的情況)
    class var computedTypeProperty: Int {
        // 這里返回一個(gè) Int 值
        return 30
    }
}
print(SomeStructure.computedTypeProperty) //10
print(SomeStructure.computedTypeProperty) //20
print(SomeClass.computedTypeProperty) //30

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末忘伞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沙兰,更是在濱河造成了極大的恐慌氓奈,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鼎天,死亡現(xiàn)場(chǎng)離奇詭異探颈,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)训措,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門伪节,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人绩鸣,你說(shuō)我怎么就攤上這事怀大。” “怎么了呀闻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵化借,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我捡多,道長(zhǎng)蓖康,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任垒手,我火速辦了婚禮蒜焊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘科贬。我一直安慰自己泳梆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著优妙,像睡著了一般乘综。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上套硼,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天卡辰,我揣著相機(jī)與錄音,去河邊找鬼邪意。 笑死看政,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抄罕。 我是一名探鬼主播允蚣,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼呆贿!你這毒婦竟也來(lái)了嚷兔?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤做入,失蹤者是張志新(化名)和其女友劉穎冒晰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體竟块,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壶运,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浪秘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒋情。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖耸携,靈堂內(nèi)的尸體忽然破棺而出棵癣,到底是詐尸還是另有隱情,我是刑警寧澤夺衍,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布狈谊,位于F島的核電站,受9級(jí)特大地震影響沟沙,放射性物質(zhì)發(fā)生泄漏河劝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一矛紫、第九天 我趴在偏房一處隱蔽的房頂上張望赎瞎。 院中可真熱鬧,春花似錦含衔、人聲如沸煎娇。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缓呛。三九已至,卻和暖如春杭隙,著一層夾襖步出監(jiān)牢的瞬間哟绊,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工痰憎, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留票髓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓铣耘,卻偏偏與公主長(zhǎng)得像洽沟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜗细,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容