国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

詳解Swift中屬性的聲明與作用

2019-11-25 16:40:34
字體:
來源:轉載
供稿:網友

一、引言

屬性將值與類,結構體,枚舉進行關聯。Swift中的屬性分為存儲屬性和計算屬性兩種,存儲屬性用于存儲一個值,其只能用于類與結構體,計算屬性用于計算一個值,其可以用于類,結構體和枚舉。

二、存儲屬性

存儲屬性使用變量或者常量來存儲一個值,在聲明存儲屬性時,可以為其設置一個默認值,也可以在構造示例是進行值的設置,屬性可以通過點語法來訪問,結構體的存儲屬性示例代碼如下:

struct MyStruct {  var property1 = 1  var property2:Int}var obj = MyStruct(property1: 1, property2: 2)//通過點語法進行屬性的訪問print(obj.property1,obj.property2)

如上結構體,如果有屬性被聲明成let常量,則此屬性不能夠被修改。還有一點需要注意,如果在創(chuàng)建結構體的實例時,使用的是let進行創(chuàng)建,則即便結構體中的屬性是變量也不可進行修改。這和類有很大區(qū)別。

還有一類存儲屬性叫做延時存儲屬性,可以設想一下這樣的情形,類的某些屬性可能并不是在每次類實例后都會用到,并且有些屬性的構造可能會消耗大量的時間,這時一個比較聰明的設計便是在類進行實例化時,這類屬性并不被構造,當次類的實例使用到這個屬性時,這個屬性才被構造出來,這樣的屬性被稱為延時存儲屬性,使用lazy關鍵字來聲明,示例如下:

//第一個類class MyClass1 {  init(){    print("MyClass1類被構造")  }}class MyClass2 {  //聲明為延時存儲屬性  lazy var body = MyClass1()}//在構造MyClass2時 并不會進行body屬性的構造 不會有打印信息var obj2 = MyClass2()//執(zhí)行下面代碼后 會有打印信息 使用body屬性使得body被構造obj2.body

注意,如果在多個線程中對延時構造屬性進行使用,不能保證其只被構造一次。

三、計算屬性

簡單的理解,計算屬性并不是獨立的用于存儲值的屬性,開發(fā)者甚至可以將其理解為一個計算方法,其主要用于通過計算來獲取或者設置其他存儲屬性的值。示例如下:

struct Circle {  //圓心  var center:(Double,Double)  //半徑  var r:Double  //周長 將其作為計算屬性  var l:Double{    get{      //計算圓的周長      return 2.0*r*M_PI    }    set{      //通過周長重新計算半徑 默認傳入的參數名為newValue      r = newValue/(M_PI*2)    }  }}var circle = Circle(center: (0,0), r: 2)print(circle.l)circle.l=24print(circle.r)

通過上面的演示代碼可以了解,l屬性并非是一個新的屬性,只是通過r屬性來計算出l,或者通過l來反推出r,其中有一點需要注意,計算屬性中可以創(chuàng)建兩個代碼塊set和get,set代碼塊是可選的,其中會默認生成一個newValue參數來傳遞外界傳進來的數據,get代碼塊是必須要實現的,當然也可以只實現get代碼塊,這時這個屬性將是只讀的計算屬性,只可以獲取,不能夠設置。還有一點需要注意,開發(fā)者也可以在set代碼塊后面自定義一個參數名來接收外界傳入的參數,示例如下:

struct Circle {  //圓心  var center:(Double,Double)  //半徑  var r:Double  //周長 將其作為計算屬性  var l:Double{    get{      //計算圓的周長      return 2.0*r*M_PI    }    set(newL){      //通過周長重新計算半徑 默認傳入的參數名為newValue      r = newL/(M_PI*2)    }  }}

只讀的計算屬性可以進行進一步的簡寫,因為沒有了set代碼塊,所以關鍵字get和括號也可以給省略掉,不會產生歧義,示例如下:

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)聽器來實現。

屬性監(jiān)聽器有willSet和didSet兩種,willSet在屬性值將要變化時執(zhí)行,didSet在屬性值已經變化時執(zhí)行,并且其中會傳入變化前后的值。示例如下:

struct Point {  var x:Double  var y:Double{    willSet{      print("將要進行值的更新設置,新的值是:",newValue)    }    didSet{      print("已經進行值得更新設置,舊的值是:",oldValue)    }  }  var center:(Double,Double){    return (x/2,y/2)  }}var point = Point(x: 3, y: 3)//將打印/* 將要進行值的更新設置,新的值是: 4.0 已經進行值得更新設置,舊的值是: 3.0 */point.y=4

willSet中默認會生成一個命名為newValue的參數,didSet中會默認生成一個命名為oldValue的參數,也可以自定義這些參數的命名,示例如下:

struct Point {  var x:Double  var y:Double{    willSet(new){      print("將要進行值的更新設置,新的值是:",new)    }    didSet(old){      print("已經進行值得更新設置,舊的值是:",old)    }  }  var center:(Double,Double){    return (x/2,y/2)  }}

五、實例屬性與類型屬性

實例屬性是針對與一個類型的實例,類型屬性則是直接針對與類型。  每對類型進行一次實例化,其實例都有一套獨立的實例屬性,而類型屬性則是類的所有實例所共用的,在Objective-C中,通常使用全局的屬性來實現這樣的效果,在Swift中,使用static關鍵字來聲明類型屬性,示例如下:

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("已經進行值得更新設置,舊的值是:",old)    }  }  var center:(Double,Double){    return (x/2,y/2)  }}//類型屬性 通過類型點語法來獲取print(Point.name,Point.subName)

注意,有一種特殊的情況是針對于類的類型計算屬性,如果其需要子類進行繼承重寫,需要將static關鍵字,換成class關鍵字,示例如下:

class SomeClass {  static var storedTypeProperty = "Some value."  static var computedTypeProperty: Int {    return 27  }  //支持子類進行重寫的計算屬性  class var overrideableComputedTypeProperty: Int {    return 107  }}

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 鲜城| 无为县| 辉县市| 延寿县| 娄底市| 绩溪县| 廉江市| 黄骅市| 青川县| 盐边县| 奉节县| 大埔县| 蒙阴县| 东至县| 肇州县| 天祝| 沙洋县| 永州市| 泰兴市| 孟津县| 唐山市| 河北省| 常山县| 郁南县| 慈利县| 册亨县| 黄平县| 包头市| 清丰县| 湘潭县| 华阴市| 云林县| 乌鲁木齐县| 施秉县| 六安市| 灵宝市| 韶山市| 无锡市| 尤溪县| 涪陵区| 且末县|