存儲屬性
1.存儲常量或者變量的
2.要么給它默認值介蛉,要么在構(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不同
//存儲屬性
var age:Int = 0
var javaScore:Double = 0.0
var htmlScore:Double = 0.0
//計算屬性
var averageScore:Double {
//獲取值
get{
print("get被調(diào)用")
return (javaScore+htmlScore)/2 //get中必須有return語句
}
//賦值
set{
print("set被調(diào)用望门,\(newValue)")
//self.averageScore = newValue 不要再set里給計算屬性賦值形娇,負責(zé)死循環(huán)
}
}
//只讀計算屬性
var averageScore2:Double {
//獲取值
get{
print("get被調(diào)用")
return (javaScore+htmlScore)/2
}
}
//只讀計算屬性-省略get{}
var averageScore3:Double {
//獲取值
print("get被調(diào)用")
return (javaScore+htmlScore)/2
}
//類屬性
static var courseCount:Int = 2
}
var stu = Student()
//使用存儲屬性
stu.age = 18
stu.javaScore = 80
stu.htmlScore = 80
//使用計算屬性
print(stu.averageScore)
stu.averageScore = 100
//只讀計算屬性
print(stu.averageScore2)
print(stu.averageScore3)
//使用類屬性
print(stu.courseCount)//不能通過對象訪問
print(Student.courseCount)
懶加載屬性(懶屬性)
懶加載屬性的引入
1.需求:需要對區(qū)間進行計算,假設(shè)該計算計算量很大筹误,很耗時,把最終計算結(jié)果放到result變量中
class CloseRange{
var start:Int = 0
var end:Int = 1000
//方案:result設(shè)計為計算屬性
var result:Int{
get{
print("開始計算...")
var res = 0
//此時采用求和操作來模擬進行大量計算桐早。
for i in self.start...self.end{
res += i
}
return res
}
}
}
var range = CloseRange()
print(range.result)
print(range.result)
print(range.result)
print(range.result)
2.思考:把result屬性定義為計算屬性有沒有什么缺陷?
3.缺陷:每訪問一次厨剪,就計算一次哄酝,計算結(jié)果沒法存儲下來。
4.改進:用的時候祷膳,才會計算陶衅,計算1次,并且能把計算結(jié)果保存下來直晨。--》引入懶加載屬性來解決
懶加載的使用:
lazy var 變量:類型 = {代碼段}()
只會賦值一次
只有在第一次使用的時候搀军,才會執(zhí)行閉包膨俐,然后把閉包返回值賦值給屬性
用的時候,才會計算罩句,計算1次焚刺,并且能把計算結(jié)果保存下來
class CloseRange{
var start:Int = 0
var end:Int = 1000
//方案:result設(shè)計為懶加載屬性
lazy var result:Int = {
()->Int in
print("開始計算...")
var res = 0
//此時采用求和操作來模擬進行大量計算。
for i in self.start...self.end{
res += i
}
return res
}()
}
var range = 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
class Student{
//存儲屬性
var age:Int = 0
var javaScore:Double = 0.0
var htmlScore:Double = 0.0
//屬性觀察器
var name:String = "test"{
willSet{
print("willSet被調(diào)用匾委,newValue的值\(a)")
}
didSet{
print("didSet被調(diào)用,oldValue的值\(b)")
}
}
}
var stu = Student()
stu.name = "zm"
stu.name = "0223"
不同使用場景剖析
懶加載屬性使用場景
場景一:位置的定位
class Location{
let latitude:Double //經(jīng)度
let longitude:Double //緯度
init(latitude:Double,longitude:Double){
self.latitude = latitude
self.longitude = longitude
}
lazy var address:String = {
//進行經(jīng)緯度分析,復(fù)雜的計算
return "xxxx"
}()
}
場景二:閱讀類APP
問題:書本的內(nèi)容到底時候加載到內(nèi)存里?
在訪問列表頁:書名氓润、封面赂乐、簡介,不需要加載書本的內(nèi)容
在詳情頁咖气,只有用戶點擊閱讀挨措,加載內(nèi)容到內(nèi)存里。
class Book{
let name:String = ""
lazy var content:String = {
//從網(wǎng)絡(luò)讀取
return "xxxx"
}()
}
屬性觀察器使用場景
有一個設(shè)備崩溪,對通電的最大電流值有要求浅役,最高30。
要求對current屬性重新設(shè)計伶唯,滿足如下:
1.< 30, 提示正常賦值
2.= 30觉既,提醒你已經(jīng)到最大值
3.>30 ,提醒用戶,當(dāng)前電流太高乳幸,此次賦值失敗瞪讼,回到原始值。
class Machine{
let max = 30 //允許通過的最大電流
var current = 10 {
willSet{
if newValue < max{
print("正常賦值")
}
if newValue == max{
print("注意粹断!當(dāng)前電流已經(jīng)到達最大值")
}
}
didSet{
if current > max{
print("注意符欠!當(dāng)前電流已經(jīng)超過最大值30,回滾到原來的值")
current = oldValue
}
}
}
}
var m1 = Machine()
m1.current = 30
m1.current = 40
m1.current = 100
print(m1.current)