屬性

屬性

  • 存儲(chǔ)屬性
  • 計(jì)算屬性
  • 屬性觀察器
  • 全局變量和局部變量
  • 類型屬性

存儲(chǔ)屬性

struct FixedLengthRange {
var firstValue: Int
let length: Int
} 

FixedLengthRange的實(shí)例包含一個(gè)名為firstValue的變量存儲(chǔ)屬性和一個(gè)名為length的常量存儲(chǔ)屬性奕谭。

常量結(jié)構(gòu)體的存儲(chǔ)屬性

如果創(chuàng)建了一個(gè)結(jié)構(gòu)體的實(shí)例并將其賦值給一個(gè)常量血柳,則無法修改該實(shí)例的任何屬性蹬昌,即使定義了變量存儲(chǔ)屬性:

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
rangeOfFourItems.firstValue = 6
// 盡管 firstValue 是個(gè)變量屬性皂贩,這里還是會(huì)報(bào)錯(cuò)

這種行為是由于結(jié)構(gòu)體(struct)屬于值類型明刷。當(dāng)值類型的實(shí)例被聲明為常量的時(shí)候满粗,它的所有屬性也就成了常量映皆。

屬于引用類型的類(class)則不一樣。把一個(gè)引用類型的實(shí)例賦給一個(gè)常量后组去,仍然可以修改該實(shí)例的變量屬性步淹。

延遲存儲(chǔ)屬性

延遲存儲(chǔ)屬性是指當(dāng)?shù)谝淮伪徽{(diào)用的時(shí)候才會(huì)計(jì)算其初始值的屬性缭裆。在屬性聲明前使用lazy來標(biāo)示一個(gè)延遲存儲(chǔ)屬性澈驼。

注意:
必須將延遲存儲(chǔ)屬性聲明成變量(使用var關(guān)鍵字),因?yàn)閷傩缘某跏贾悼赡茉趯?shí)例構(gòu)造完成之后才會(huì)得到挎塌。而常量屬性在構(gòu)造過程完成之前必須要有初始值勃蜘,因此無法聲明成延遲屬性缭贡。

下面的例子使用了延遲存儲(chǔ)屬性來避免復(fù)雜類中不必要的初始化。例子中定義了DataImporter和DataManager兩個(gè)類谍失,下面是部分代碼:

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()
var data = [String]()
// 這是提供數(shù)據(jù)管理功能
}

let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// DataImporter 實(shí)例的 importer 屬性還沒有被創(chuàng)建

print(manager.importer.fileName)
// DataImporter 實(shí)例的 importer 屬性現(xiàn)在被創(chuàng)建了
// 輸出 "data.txt”

注意:
如果一個(gè)被標(biāo)記為lazy的屬性在沒有初始化時(shí)就同時(shí)被多個(gè)線程訪問止潮,則無法保證該屬性只會(huì)被初始化一次喇闸。

計(jì)算屬性

計(jì)算屬性不直接存儲(chǔ)值,而是提供一個(gè) getter 和一個(gè)可選的 setter燃乍,來間接獲取和設(shè)置其他屬性或變量的值刻蟹。

struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
var center: Point {
    get {
        let centerX = origin.x + (size.width / 2)
        let centerY = origin.y + (size.height / 2)
        return Point(x: centerX, y: centerY)
    }
    set(newCenter) {
        origin.x = newCenter.x - (size.width / 2)
        origin.y = newCenter.y - (size.height / 2)
    }
}
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// 輸出 "square.origin is now at (10.0, 10.0)”

便捷 setter 聲明

如果計(jì)算屬性的 setter 沒有定義表示新值的參數(shù)名痢艺,則可以使用默認(rèn)名稱newValue堤舒。下面是使用了便捷 setter 聲明的Rect結(jié)構(gòu)體代碼:

struct AlternativeRect {
var origin = Point()
var size = Size()
var center: Point {
    get {
        let centerX = origin.x + (size.width / 2)
        let centerY = origin.y + (size.height / 2)
        return Point(x: centerX, y: centerY)
    }
    set {
        origin.x = newValue.x - (size.width / 2)
        origin.y = newValue.y - (size.height / 2)
    }
}
}

只讀計(jì)算屬性

只有 getter 沒有 setter 的計(jì)算屬性就是只讀計(jì)算屬性舌缤。只讀計(jì)算屬性總是返回一個(gè)值国撵,可以通過點(diǎn)運(yùn)算符訪問介牙,但不能設(shè)置新的值环础。

注意:
必須使用var關(guān)鍵字定義計(jì)算屬性,包括只讀計(jì)算屬性线得,因?yàn)樗鼈兊闹挡皇枪潭ǖ墓峁场et關(guān)鍵字只用來聲明常量屬性角雷,表示初始化后再也無法修改的值。

只讀計(jì)算屬性的聲明可以去掉get關(guān)鍵字和花括號(hào):

struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
    return width * height * depth
}

let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// 輸出 "the volume of fourByFiveByTwo is 40.0

屬性觀察器

可以為屬性添加如下的一個(gè)或全部觀察器:

可以為除了延遲存儲(chǔ)屬性之外的其他存儲(chǔ)屬性添加屬性觀察器季二,也可以通過重寫屬性的方式為繼承的屬性(包括存儲(chǔ)屬性和計(jì)算屬性)添加屬性觀察器。

  • willSet在新的值被設(shè)置之前調(diào)用
  • didSet在新的值被設(shè)置之后立即調(diào)用

willSet觀察器會(huì)將新的屬性值作為常量參數(shù)傳入刻蚯,在willSet的實(shí)現(xiàn)代碼中可以為這個(gè)參數(shù)指定一個(gè)名稱,如果不指定則參數(shù)仍然可用桑嘶,這時(shí)使用默認(rèn)名稱newValue表示炊汹。

類似地,didSet觀察器會(huì)將舊的屬性值作為參數(shù)傳入逃顶,可以為該參數(shù)命名或者使用默認(rèn)參數(shù)名oldValue讨便。

注意:
父類的屬性在子類的構(gòu)造器中被賦值時(shí),它在父類中的willSet和didSet觀察器會(huì)被調(diào)用以政。

例子如下:

class StepCounter {
var totalSteps: Int = 0 {
    willSet(newTotalSteps) {
        print("About to set totalSteps to \(newTotalSteps)")
    }
    didSet {
        if totalSteps > oldValue  {
            print("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

注意:
如果在一個(gè)屬性的didSet觀察器里為它賦值霸褒,這個(gè)值會(huì)替換該觀察器之前設(shè)置的值。

全局變量和局部變量

類型屬性

即static關(guān)鍵字標(biāo)注的屬性盈蛮,只有一份废菱,可用在結(jié)構(gòu)體,枚舉和類中抖誉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末殊轴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子孽文,更是在濱河造成了極大的恐慌塑悼,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件草雕,死亡現(xiàn)場離奇詭異嘱巾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)问拘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顶岸,“玉大人,你說我怎么就攤上這事卷谈。” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我析二,道長,這世上最難降的妖魔是什么准谚? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上朋其,老公的妹妹穿的比我還像新娘秒裕。我一直安慰自己喇潘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布粱栖。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪价认。 梳的紋絲不亂的頭發(fā)上忙迁,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天佛南,我揣著相機(jī)與錄音呀页,去河邊找鬼。 笑死著摔,一個(gè)胖子當(dāng)著我的面吹牛摹察,可吹牛的內(nèi)容都是我干的供嚎。 我是一名探鬼主播劝赔,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎院领,沒想到半個(gè)月后扒寄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體课竣,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡路捧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年零渐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苍苞。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡歉铝,死狀恐怖太示,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情囱晴,我是刑警寧澤速缆,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布破停,位于F島的核電站黑界,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹬竖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一页衙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阴绢,春花似錦店乐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至左电,卻和暖如春廉侧,著一層夾襖步出監(jiān)牢的瞬間页响,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國打工段誊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闰蚕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓连舍,卻偏偏與公主長得像没陡,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子索赏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

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