存儲屬性
1.存儲常量或者變量的
2.要么給它默認(rèn)值,要么在構(gòu)造方法里初始化
計算屬性
1.計算屬性不直接存儲值
2.訪問時候調(diào)用get,賦值調(diào)用set,類似java里的封裝
3.get里一定要有return
4.set中有一個內(nèi)置的newValue變量,用于接收外界賦的新值
5.set里不能給當(dāng)前的計算屬性賦值石洗,否則死循環(huán)
6.只讀計算屬性:只提供get砖织,沒有set阀参,在寫的時候可以省略get{}
類屬性
1.類屬性用static修飾
2.類屬性是和類關(guān)聯(lián)的,而不是單獨屬于某個對象
3.只能通過類名來訪問,這點和java語言不同
classStudent{//存儲屬性varage:Int=0varjavaScore:Double=0.0varhtmlScore:Double=0.0//計算屬性varaverageScore:Double{//獲取值get{print("get被調(diào)用")return(javaScore+htmlScore)/2//get中必須有return語句}//賦值set{print("set被調(diào)用,\(newValue)")//self.averageScore = newValue? 不要再set里給計算屬性賦值讹语,否則死循環(huán)}}//只讀計算屬性varaverageScore2:Double{//獲取值get{print("get被調(diào)用")return(javaScore+htmlScore)/2}}//只讀計算屬性-省略get{}varaverageScore3:Double{//獲取值print("get被調(diào)用")return(javaScore+htmlScore)/2}//類屬性staticvarcourseCount:Int=2}varstu=Student()//使用存儲屬性stu.age=18stu.javaScore=90stu.htmlScore=60//使用計算屬性print(stu.averageScore)stu.averageScore=100//只讀計算屬性print(stu.averageScore2)print(stu.averageScore3)//使用類屬性print(stu.courseCount)//不能通過對象訪問print(Student.courseCount)
懶加載屬性(懶屬性)
懶加載屬性的引入
需求:需要對區(qū)間進(jìn)行計算搞糕,假設(shè)該計算計算量很大勇吊,很耗時,把最終計算結(jié)果放到result變量中
class CloseRange{varstart:Int=0varend:Int=1000//方案:result設(shè)計為計算屬性varresult:Int{get{print("開始計算...")varres=0//此時采用求和操作來模擬進(jìn)行大量計算。fori in self.start...self.end{res+=i}returnres}}varrange=CloseRange()print(range.result)print(range.result)print(range.result)print(range.result)
思考:把result屬性定義為計算屬性有沒有什么缺陷窍仰?
缺陷:每訪問一次汉规,就計算一次,計算結(jié)果沒法存儲下來辈赋。
改進(jìn):用的時候鲫忍,才會計算,計算1次钥屈,并且能把計算結(jié)果保存下來悟民。引入懶加載屬性來解決
懶加載的使用:
lazyvar變量:類型={代碼段}()
1.只會賦值一次
2.只有在第一次使用的時候,才會執(zhí)行閉包篷就,然后把閉包返回值賦值給屬性
3.用的時候射亏,才會計算,計算1次竭业,并且能把計算結(jié)果保存下來
class CloseRange{varstart:Int=0varend:Int=1000//方案:result設(shè)計為懶加載屬性lazyvarresult:Int={()->Int? inprint("開始計算...")varres=0//此時采用求和操作來模擬進(jìn)行大量計算智润。fori in self.start...self.end{res+=i}returnres}()}varrange=CloseRange()print(range.result)//只有第一次調(diào)用的時候執(zhí)行閉包,干活只干1次未辆!print(range.result)print(range.result)print(range.result)
屬性觀察器
1.監(jiān)聽和響應(yīng)屬性值的變化
2.針對存儲屬性和類屬性的變化
3.怎么實現(xiàn)窟绷?為觀察的屬性添加觀察器
willSet 在賦新值之前調(diào)用,使用內(nèi)置變量newValue
didSet 賦新值之后調(diào)用,使用oldValue
classStudent{//存儲屬性varage:Int=0varjavaScore:Double=0.0varhtmlScore:Double=0.0//屬性觀察器varname:String="test"{willSet{print("willSet被調(diào)用咐柜,newValue的值\(a)")}didSet{print("didSet被調(diào)用,oldValue的值\(b)")}}}varstu=Student()stu.name="miao"stu.name="123"
不同使用場景剖析
懶加載屬性使用場景
場景一:位置的定位
classLocation{let latitude:Double//經(jīng)度let longitude:Double//緯度init(latitude:Double,longitude:Double){self.latitude=latitude? ? ? ? self.longitude=longitude}lazyvaraddress:String={//進(jìn)行經(jīng)緯度分析,復(fù)雜的計算return"xxxx"}()}
場景二:閱讀類APP
問題:書本的內(nèi)容到底時候加載到內(nèi)存里兼蜈?
在訪問列表頁:書名、封面拙友、簡介为狸,不需要加載書本的內(nèi)容
在詳情頁,只有用戶點擊閱讀遗契,加載內(nèi)容到內(nèi)存里辐棒。
classBook{letname:String=""lazyvarcontent:String={//從網(wǎng)絡(luò)讀取return"xx"}()}
屬性觀察器使用場景
有一個設(shè)備,對通電的最大電流值有要求,最高30漾根。
要求對current屬性重新設(shè)計泰涂,滿足如下:
< 30, 提示正常賦值
= 30,提醒你已經(jīng)到最大值
30 ,提醒用戶立叛,當(dāng)前電流太高负敏,此次賦值失敗,回到原始值秘蛇。
classMachine{letmax=30//允許通過的最大電流varcurrent=10{willSet{ifnewValue<max{print("正常賦值")}ifnewValue==max{print("注意其做!當(dāng)前電流已經(jīng)到達(dá)最大值")}}didSet{ifcurrent>max{print("注意!當(dāng)前電流已經(jīng)超過最大值30赁还,回滾到原來的值")current=oldValue}}}}varm1=Machine()m1.current=20m1.current=30m1.current=100print(m1.current)