存儲(chǔ)屬性
其實(shí)Swift中的存儲(chǔ)屬性就是以前學(xué)習(xí)OC中的普通屬性, 在結(jié)構(gòu)體或者類中定義的屬性, 默認(rèn)就是存儲(chǔ)屬性
*/
struct Person {
var name: String
var age: Int
}
var p:Person = Person(name: "lnj", age: 30)
p.name = "hm"
p.age = 50
/*
常量存儲(chǔ)屬性
常量存儲(chǔ)屬性只能在定義時(shí)或構(gòu)造時(shí)修改, 構(gòu)造好一個(gè)對(duì)象之后不能對(duì)常量存儲(chǔ)屬性進(jìn)行修改
*/
struct Person2 {
var name: String
var age: Int
let card: String // 身份證
}
var p2: Person2 = Person2(name: "lnj", age: 30, card: "123456")
p2.name = "hm"
p2.age = 50
// 構(gòu)造好對(duì)象之后不能修改常量存儲(chǔ)屬性
//p2.card = "56789"
/*
結(jié)構(gòu)體和類常量與存儲(chǔ)屬性的關(guān)系
結(jié)構(gòu)體和枚舉是值類型
類是引用類型
*/
struct Person3 {
var name: String
var age: Int
}
let p3: Person3 = Person3(name: "lnj", age: 30)
// 因?yàn)榻Y(jié)構(gòu)體是值類型, 所以不能修改結(jié)構(gòu)體常量中的屬性
// 不能修改結(jié)構(gòu)體/枚舉常量對(duì)象中的值, 因?yàn)樗赶虻膶?duì)象是一個(gè)常量
//p3.name = "hm"
// 不能修改結(jié)構(gòu)體常量對(duì)象的值
//p3 = Person(name: "hm", age: 50)
class Person4 {
var name: String = "lnj"
var age: Int = 30
}
let p4:Person4 = Person4()
// 可以修改類常量中的值, 因?yàn)樗赶虻膶?duì)象不是一個(gè)常量
p4.name = "hm"
// 不可以修改類常量的指向
//p4 = Person4()
/*
延遲存儲(chǔ)屬性
Swift語(yǔ)言中所有的存儲(chǔ)屬性必須有初始值, 也就是當(dāng)構(gòu)造完一個(gè)對(duì)象后, 對(duì)象中所有的存儲(chǔ)屬性必須有初始值, 但是也有例外, 其中延遲存儲(chǔ)屬性可以將屬性的初始化推遲到該屬性第一次被調(diào)用的時(shí)候
懶加載應(yīng)用場(chǎng)景:
1.有可能不會(huì)用到
2.依賴于其它值
*/
class Line {
var start:Double = 0.0
var end: Double = 0.0
// 如果不是lazy屬性, 定義的時(shí)候?qū)ο筮€沒(méi)有初始化, 所以不能訪問(wèn)self
// 如果加上lazy, 代表使用時(shí)才會(huì)加載, 也就是使用到length屬性時(shí)才會(huì)調(diào)用self,
// 而訪問(wèn)一個(gè)類的屬性必須通過(guò)對(duì)象方法, 所以訪問(wèn)時(shí)對(duì)象已經(jīng)初始化完成了, 可以使用self
lazy var length: Double = self.getLenght()
// 通過(guò)閉包懶加載
lazy var container: Array<AnyObject> = {
print("懶加載")
// return self.end - self.start
var arrM = []
return arrM as [AnyObject]
}()
func getLenght() ->Double
{
print("懶加載")
return end - start
}
}
var line = Line()
line.end = 150.0
//print(line.getLenght())
print("創(chuàng)建對(duì)象完畢")
print(line.length)
var arrM = line.container
arrM.append("1")
arrM.append(5)
print(arrM)
/*
計(jì)算屬性
1.Swift中的計(jì)算屬性不直接存儲(chǔ)值, 跟存儲(chǔ)屬性不同, 沒(méi)有任何的"后端存儲(chǔ)與之對(duì)應(yīng)"
2.計(jì)算屬性用于計(jì)算, 可以實(shí)現(xiàn)setter和getter這兩種計(jì)算方法
3.枚舉不可以有存儲(chǔ)屬性, 但是允許有計(jì)算屬性
setter 對(duì)象.屬性 = 值
getter var value = 對(duì)象.屬性
*/
struct Rect {
var origion: (x: Double, y: Double) = (0, 0)
var size: (w: Double, h: Double) = (0, 0)
// 由于center的值是通過(guò)起點(diǎn)和寬高計(jì)算出來(lái)的, 所以沒(méi)有必要提供一個(gè)存儲(chǔ)屬性
// var center: (x: Double, y: Double) = (0, 0)
var center: (x: Double, y: Double) {
get{
// print("get")
return (origion.x + size.w/2, origion.y + size.h/2)
}
// set(newCenter){
set{
// print("set (newCenter)")
// 注意: 計(jì)算屬性不具備存儲(chǔ)功能, 所以不能給計(jì)算屬性賦值, 如果賦值會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤
// 注意: setter可以自己傳遞一個(gè)參數(shù), 也可以使用系統(tǒng)默認(rèn)的參數(shù)newValue
// 如果要使用系統(tǒng)自帶的參數(shù), 必須刪除自定義參數(shù)
// origion.x = newCenter.x - size.w / 2
// origion.y = newCenter.y - size.h / 2
origion.x = newValue.x - size.w / 2
origion.y = newValue.y - size.h / 2
}
}
}
var r = Rect()
r.origion = (0, 0)
r.size = (100, 100)
//r.center = ((r.origion.x + r.size.w) / 2, (r.origion.y + r.size.h) / 2)
print("center.x = (r.center.x) center.y = (r.center.y)")
r.center = (100, 100)
print("origion.x = (r.origion.x) origion.y = (r.origion.y)")
print("center.x = (r.center.x) center.y = (r.center.y)")
/*
只讀計(jì)算屬性
對(duì)應(yīng)OC中的readonly屬性, 所謂的只讀屬性就是只提供了getter方法, 沒(méi)有提供setter方法
*/
class Line2 {
var start:Double = 0.0
var end: Double = 0.0
// 只讀屬性, 只讀屬性必須是變量var, 不能是常量let
// 例如想獲取長(zhǎng)度, 只能通過(guò)計(jì)算獲得, 而不需要外界設(shè)置, 可以設(shè)置為只讀計(jì)算屬性
var length: Double{
// 只讀屬性的簡(jiǎn)寫(xiě), 可以省略get{}
// get{
return end - start
// }
}
}
var line2 = Line2()
line2.end = 100
print(line2.length)
/*
屬性觀察器,類似OC中的KVO, 可以用于監(jiān)聽(tīng)屬性什么時(shí)候被修改, 只有屬性被修改才會(huì)調(diào)用
有兩種屬性觀察器:
1.willSet, 在設(shè)置新值之前調(diào)用
2.didSet, 在設(shè)置新值之后調(diào)用
可以直接為除計(jì)算屬性和lazy屬性之外的存儲(chǔ)屬性添加屬性觀察器, 但是可以在繼承類中為父類的計(jì)算屬性提供屬性觀察器
因?yàn)樵谟?jì)算屬性中也可以監(jiān)聽(tīng)到屬性的改變, 所以給計(jì)算屬性添加屬性觀察器沒(méi)有任何意義
*/
class Line3 {
var start:Double = 0.0{
willSet{
print("willSet newValue = (newValue)")
}
didSet{
print("didSet oldValue = (oldValue)")
}
}
var end: Double = 0.0
}
var l = Line3()
l.start = 10.0
/*
類屬性
在結(jié)構(gòu)體和枚舉中用static
在類中使用class, 并且類中不允許將存儲(chǔ)屬性設(shè)置為類屬性
*/
struct Person5 {
// 普通的屬性是每個(gè)對(duì)象一份
var name: String = "lnj"
// 類屬性是素有對(duì)象共用一份
static var gender:String = "man"
static var age:Int{
return 30
}
func show()
{
print("gender = (Person5.gender) name = (name)")
}
}
var p5 = Person5()
//print("gender = (p.gender)")
print("gender = (Person5.gender)")
var p6 = Person5()
// 類屬性是所有對(duì)象共用一份
print("gender = (Person5.gender)")
p5.show()
// 可以將計(jì)算屬性設(shè)置為類屬性
print("age = (Person5.age)")
class Person6 {
// 普通的屬性是每個(gè)對(duì)象一份
var name: String = "lnj"
// 類中不允許將存儲(chǔ)屬性定義為類屬性
// class var gender:String = "man"
// 類中只能將計(jì)算屬性定義為類屬性
class var age:Int{
return 30
}
func show()
{
print("age = (Person6.age)")
}
}
var p7 = Person6()
print("age = (Person6.age)")
p7.show()