詳解Swift中屬性的聲明與作用
一、引言
屬性將值與類,結(jié)構(gòu)體,枚舉進行關(guān)聯(lián)。Swift中的屬性分為存儲屬性和計算屬性兩種,存儲屬性用于存儲一個值,其只能用于類與結(jié)構(gòu)體,計算屬性用于計算一個值,其可以用于類,結(jié)構(gòu)體和枚舉。
二、存儲屬性
存儲屬性使用變量或者常量來存儲一個值,在聲明存儲屬性時,可以為其設置一個默認值,也可以在構(gòu)造示例是進行值的設置,屬性可以通過點語法來訪問,結(jié)構(gòu)體的存儲屬性示例代碼如下:
struct MyStruct {
var property1 = 1
var property2:Int
}
var obj = MyStruct(property1: 1, property2: 2)
//通過點語法進行屬性的訪問
print(obj.property1,obj.property2)
如上結(jié)構(gòu)體,如果有屬性被聲明成let常量,則此屬性不能夠被修改。還有一點需要注意,如果在創(chuàng)建結(jié)構(gòu)體的實例時,使用的是let進行創(chuàng)建,則即便結(jié)構(gòu)體中的屬性是變量也不可進行修改。這和類有很大區(qū)別。
還有一類存儲屬性叫做延時存儲屬性,可以設想一下這樣的情形,類的某些屬性可能并不是在每次類實例后都會用到,并且有些屬性的構(gòu)造可能會消耗大量的時間,這時一個比較聰明的設計便是在類進行實例化時,這類屬性并不被構(gòu)造,當次類的實例使用到這個屬性時,這個屬性才被構(gòu)造出來,這樣的屬性被稱為延時存儲屬性,使用lazy關(guān)鍵字來聲明,示例如下:
//第一個類
class MyClass1 {
init(){
print("MyClass1類被構(gòu)造")
}
}
class MyClass2 {
//聲明為延時存儲屬性
lazy var body = MyClass1()
}
//在構(gòu)造MyClass2時 并不會進行body屬性的構(gòu)造 不會有打印信息
var obj2 = MyClass2()
//執(zhí)行下面代碼后 會有打印信息 使用body屬性使得body被構(gòu)造
obj2.body
注意,如果在多個線程中對延時構(gòu)造屬性進行使用,不能保證其只被構(gòu)造一次。
三、計算屬性
簡單的理解,計算屬性并不是獨立的用于存儲值的屬性,開發(fā)者甚至可以將其理解為一個計算方法,其主要用于通過計算來獲取或者設置其他存儲屬性的值。示例如下:
struct Circle {
//圓心
var center:(Double,Double)
//半徑
var r:Double
//周長 將其作為計算屬性
var l:Double{
get{
//計算圓的周長
return 2.0*r*M_PI
}
set{
//通過周長重新計算半徑 默認傳入的參數(shù)名為newValue
r = newValue/(M_PI*2)
}
}
}
var circle = Circle(center: (0,0), r: 2)
print(circle.l)
circle.l=24
print(circle.r)
通過上面的演示代碼可以了解,l屬性并非是一個新的屬性,只是通過r屬性來計算出l,或者通過l來反推出r,其中有一點需要注意,計算屬性中可以創(chuàng)建兩個代碼塊set和get,set代碼塊是可選的,其中會默認生成一個newValue參數(shù)來傳遞外界傳進來的數(shù)據(jù),get代碼塊是必須要實現(xiàn)的,當然也可以只實現(xiàn)get代碼塊,這時這個屬性將是只讀的計算屬性,只可以獲取,不能夠設置。還有一點需要注意,開發(fā)者也可以在set代碼塊后面自定義一個參數(shù)名來接收外界傳入的參數(shù),示例如下:
struct Circle {
//圓心
var center:(Double,Double)
//半徑
var r:Double
//周長 將其作為計算屬性
var l:Double{
get{
//計算圓的周長
return 2.0*r*M_PI
}
set(newL){
//通過周長重新計算半徑 默認傳入的參數(shù)名為newValue
r = newL/(M_PI*2)
}
}
}
只讀的計算屬性可以進行進一步的簡寫,因為沒有了set代碼塊,所以關(guān)鍵字get和括號也可以給省略掉,不會產(chǎn)生歧義,示例如下:
struct Point {
var x:Double
var y:Double
var center:(Double,Double){
return (x/2,y/2)
}
}
四、屬性監(jiān)聽器
Swift中的計算屬性中的get和set方法和Objective-C中的get和set方法其實并非是一回事,Objective-C提供set和get方法可以讓開發(fā)者在屬性將要獲取或者設置的時候來進行一些自定義的操作,這部分的開發(fā)需求在Swift中通過屬性監(jiān)聽器來實現(xiàn)。
屬性監(jiān)聽器有willSet和didSet兩種,willSet在屬性值將要變化時執(zhí)行,didSet在屬性值已經(jīng)變化時執(zhí)行,并且其中會傳入變化前后的值。示例如下:
struct Point {
var x:Double
var y:Double{
willSet{
print("將要進行值的更新設置,新的值是:",newValue)
}
didSet{
print("已經(jīng)進行值得更新設置,舊的值是:",oldValue)
}
}
var center:(Double,Double){
return (x/2,y/2)
}
}
var point = Point(x: 3, y: 3)
//將打印
/*
將要進行值的更新設置,新的值是: 4.0
已經(jīng)進行值得更新設置,舊的值是: 3.0
*/
point.y=4
willSet中默認會生成一個命名為newValue的參數(shù),didSet中會默認生成一個命名為oldValue的參數(shù),也可以自定義這些參數(shù)的命名,示例如下:
struct Point {
var x:Double
var y:Double{
willSet(new){
print("將要進行值的更新設置,新的值是:",new)
}
didSet(old){
print("已經(jīng)進行值得更新設置,舊的值是:",old)
}
}
var center:(Double,Double){
return (x/2,y/2)
}
}
五、實例屬性與類型屬性
實例屬性是針對與一個類型的實例,類型屬性則是直接針對與類型。 每對類型進行一次實例化,其實例都有一套獨立的實例屬性,而類型屬性則是類的所有實例所共用的,在Objective-C中,通常使用全局的屬性來實現(xiàn)這樣的效果,在Swift中,使用static關(guān)鍵字來聲明類型屬性,示例如下:
struct Point {
//類型存儲屬性
static var name:String = "Point"
//類型計算屬性
static var subName:String{
return "sub"+name
}
var x:Double
var y:Double{
willSet(new){
print("將要進行值的更新設置,新的值是:",new)
}
didSet(old){
print("已經(jīng)進行值得更新設置,舊的值是:",old)
}
}
var center:(Double,Double){
return (x/2,y/2)
}
}
//類型屬性 通過類型點語法來獲取
print(Point.name,Point.subName)
注意,有一種特殊的情況是針對于類的類型計算屬性,如果其需要子類進行繼承重寫,需要將static關(guān)鍵字,換成class關(guān)鍵字,示例如下:
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 27
}
//支持子類進行重寫的計算屬性
class var overrideableComputedTypeProperty: Int {
return 107
}
}
相關(guān)文章
Python數(shù)據(jù)結(jié)構(gòu)與算法之圖的最短路徑(Dijkstra算法)完整實例
這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)與算法之圖的最短路徑(Dijkstra算法),結(jié)合完整實例形式分析了Python圖的最短路徑算法相關(guān)原理與實現(xiàn)技巧,需要的朋友可以參考下2017-12-12
Pytorch 實現(xiàn)凍結(jié)指定卷積層的參數(shù)
今天小編就為大家分享一篇Pytorch 實現(xiàn)凍結(jié)指定卷積層的參數(shù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
淺析Python中常見數(shù)據(jù)脫敏技術(shù)應用與對比
數(shù)據(jù)脫敏通過對敏感數(shù)據(jù)進行轉(zhuǎn)換,確保其在保護隱私的同時仍能用于開發(fā),本文為大家整理了一些常見的數(shù)據(jù)脫敏技術(shù),感興趣的小伙伴可以了解下2025-02-02
python計算數(shù)字或者數(shù)組的階乘的實現(xiàn)
本文主要介紹了python計算數(shù)字或者數(shù)組的階乘,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08
Python?matplotlib中更換畫布背景顏色的3種方法
這篇文章主要給大家介紹了關(guān)于Python?matplotlib中更換畫布背景顏色的3種方法,在Matplotlib中,我們可以使用set_facecolor()方法來設置背景顏色,文中通過圖文以及代碼介紹的非常詳細,需要的朋友可以參考下2023-11-11

