存儲(chǔ)屬性
存儲(chǔ)常量或者變量的,要么給它默認(rèn)值,要么在構(gòu)造方法里初始化
計(jì)算屬性
計(jì)算屬性不直接存儲(chǔ)值
訪問(wèn)時(shí)候調(diào)用get,賦值調(diào)用set,類似java里的封裝
get里一定要有return
set中有一個(gè)內(nèi)置的newValue變量,用于接收外界賦的新值
set里不能給當(dāng)前的計(jì)算屬性賦值嘱根,否則死循環(huán)
只讀計(jì)算屬性:只提供get恋博,沒(méi)有set状原,在寫的時(shí)候可以省略get{}
類屬性
類屬性用static修飾
類屬性是和類關(guān)聯(lián)的菩收,而不是單獨(dú)屬于某個(gè)對(duì)象
只能通過(guò)類名來(lái)訪問(wèn)拨齐,這點(diǎn)和java不同
class Student{
//存儲(chǔ)屬性
var age:Int = 0
var javaScore:Double = 0.0
var htmlScore:Double = 0.0
//計(jì)算屬性
var averageScore:Double {
//獲取值
get{
print("get被調(diào)用")
return (javaScore+htmlScore)/2 //get中必須有return語(yǔ)句
}
//賦值
set{
print("set被調(diào)用,\(newValue)")
//self.averageScore = newValue 不要再set里給計(jì)算屬性賦值驰贷,否則死循環(huán)
}
}
//只讀計(jì)算屬性
var averageScore2:Double {
//獲取值
get{
print("get被調(diào)用")
return (javaScore+htmlScore)/2
}
}
//只讀計(jì)算屬性-省略get{}
var averageScore3:Double {
//獲取值
print("get被調(diào)用")
return (javaScore+htmlScore)/2
}
//類屬性
static var courseCount:Int = 2
}
var stu = Student()
//使用存儲(chǔ)屬性
stu.age = 18
stu.javaScore = 90
stu.htmlScore = 60
//使用計(jì)算屬性
print(stu.averageScore)
stu.averageScore = 100
//只讀計(jì)算屬性
print(stu.averageScore2)
print(stu.averageScore3)
//使用類屬性
print(stu.courseCount)//不能通過(guò)對(duì)象訪問(wèn)
print(Student.courseCount)
懶加載屬性(懶屬性)
懶加載屬性的引入
需求:需要對(duì)區(qū)間進(jìn)行計(jì)算盛嘿,假設(shè)該計(jì)算計(jì)算量很大,很耗時(shí),把最終計(jì)算結(jié)果放到result變量中
class CloseRange{
var start:Int = 0
var end:Int = 1000
//方案:result設(shè)計(jì)為計(jì)算屬性
var result:Int{
get{
print("開(kāi)始計(jì)算...")
var res = 0
//此時(shí)采用求和操作來(lái)模擬進(jìn)行大量計(jì)算括袒。
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)
思考:把result屬性定義為計(jì)算屬性有沒(méi)有什么缺陷次兆?
缺陷:每訪問(wèn)一次,就計(jì)算一次锹锰,計(jì)算結(jié)果沒(méi)法存儲(chǔ)下來(lái)芥炭。
改進(jìn):用的時(shí)候,才會(huì)計(jì)算恃慧,計(jì)算1次园蝠,并且能把計(jì)算結(jié)果保存下來(lái)。--》引入懶加載屬性來(lái)解決
懶加載的使用:
lazy var 變量:類型 = { 代碼段}()
只會(huì)賦值一次
只有在第一次使用的時(shí)候痢士,才會(huì)執(zhí)行閉包彪薛,然后把閉包返回值賦值給屬性
用的時(shí)候,才會(huì)計(jì)算,計(jì)算1次善延,并且能把計(jì)算結(jié)果保存下來(lái)
class CloseRange{
var start:Int = 0
var end:Int = 1000
//方案:result設(shè)計(jì)為懶加載屬性
lazy var result:Int = {
()->Int in
print("開(kāi)始計(jì)算...")
var res = 0
//此時(shí)采用求和操作來(lái)模擬進(jìn)行大量計(jì)算少态。
for i in self.start...self.end{
res += i
}
return res
}()
}
var range = CloseRange()
print(range.result)//只有第一次調(diào)用的時(shí)候執(zhí)行閉包,干活只干1次易遣!
print(range.result)
print(range.result)
print(range.result)
屬性觀察器
監(jiān)聽(tīng)和響應(yīng)屬性值的變化
針對(duì)存儲(chǔ)屬性和類屬性的變化
怎么實(shí)現(xiàn)彼妻?為觀察的屬性添加觀察器
willSet 在賦新值之前調(diào)用,使用內(nèi)置變量newValue
didSet 賦新值之后調(diào)用,使用oldValue
class Student{
//存儲(chǔ)屬性
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 = "miao"
stu.name = "123"
不同使用場(chǎng)景剖析
懶加載屬性使用場(chǎng)景
場(chǎng)景一:位置的定位
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ìn)行經(jīng)緯度分析,復(fù)雜的計(jì)算
return "xxxx"
}()
}
場(chǎng)景二:閱讀類APP
問(wèn)題:書(shū)本的內(nèi)容到底時(shí)候加載到內(nèi)存里澳骤?
在訪問(wèn)列表頁(yè):書(shū)名、封面澜薄、簡(jiǎn)介为肮,不需要加載書(shū)本的內(nèi)容
在詳情頁(yè),只有用戶點(diǎn)擊閱讀肤京,加載內(nèi)容到內(nèi)存里颊艳。
class Book{
let name:String = ""
lazy var content:String = {
//從網(wǎng)絡(luò)讀取
return "xx"
}()
}
屬性觀察器使用場(chǎng)景
有一個(gè)設(shè)備,對(duì)通電的最大電流值有要求忘分,最高30棋枕。
要求對(duì)current屬性重新設(shè)計(jì),滿足如下:
1.< 30, 提示正常賦值
2.= 30妒峦,提醒你已經(jīng)到最大值
3.>30 ,提醒用戶重斑,當(dāng)前電流太高,此次賦值失敗肯骇,回到原始值窥浪。
class Machine{
let max = 30 //允許通過(guò)的最大電流
var current = 10 {
willSet{
if newValue < max{
print("正常賦值")
}
if newValue == max{
print("注意!當(dāng)前電流已經(jīng)到達(dá)最大值")
}
}
didSet{
if current > max{
print("注意笛丙!當(dāng)前電流已經(jīng)超過(guò)最大值30漾脂,回滾到原來(lái)的值")
current = oldValue
}
}
}
}
var m1 = Machine()
m1.current = 20
m1.current = 30
m1.current = 100
print(m1.current)