天天看點

swift 屬性

屬性在前面的枚舉,類,結構體中都已經使用過,本章介紹屬性的性質和方法

​​?​​

<col>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

​<code>​struct​</code>​ ​<code>​FixedLengthRange {​</code>​

​<code>​var firstValue: Int​</code>​

​<code>​let length: Int​</code>​

​<code>​}​</code>​

​<code>​var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)​</code>​

​<code>​// the range represents integer values 0, 1, and 2​</code>​

​<code>​rangeOfThreeItems.firstValue = 6​</code>​

​<code>​// the range now represents integer values 6, 7, and 8​</code>​

​<code>​//如果結構體的執行個體就是let類型,則第一次初始化後,不能再修改其任何屬性的值​</code>​

​<code>​let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)​</code>​

​<code>​// this range represents integer values 0, 1, 2, and 3​</code>​

​<code>​rangeOfFourItems.firstValue = 6​</code>​

​<code>​// 将會報錯​</code>​

但是類不同意結構體,因為類是指針類型,将指針類型的執行個體指派給一個常量,仍然可以修改其變量成員的值。

延遲存儲屬性,在屬性聲明前部加@lazy關鍵字,必須是var類型的屬性才能是延遲屬性,延遲屬性隻有在用到時才會被計算。

15

16

17

18

19

20

21

​<code>​class​</code>​ ​<code>​DataImporter {​</code>​

​<code>​/*​</code>​

​<code>​該類的功能是從外部檔案導入資料​</code>​

​<code>​*/​</code>​

​<code>​var fileName = ​</code>​​<code>​"data.txt"​</code>​

​<code>​// 其他資料導入等功能此處省略​</code>​

​<code>​class​</code>​ ​<code>​DataManager {​</code>​

​<code>​@lazy var importer = DataImporter()​</code>​

​<code>​var data = String[]()​</code>​

​<code>​// 其他資料管理功能此處省略​</code>​

​<code>​let manager = DataManager()​</code>​

​<code>​manager.data += ​</code>​​<code>​"Some data"​</code>​

​<code>​manager.data += ​</code>​​<code>​"Some more data"​</code>​

​<code>​//在下面的語句執行以前,importer未被建立​</code>​

​<code>​println(manager.importer.fileName)​</code>​

​<code>​// 當第一次用到importer的時候,才會生成執行個體,列印"data.txt"​</code>​

存儲屬性:我認為就是一般的屬性,直接存儲了變量或常量,可直接通過後點(.)獲得或設定其值

計算屬性:有get方法和set(可選)方法的屬性

22

23

24

25

26

27

28

​<code>​struct​</code>​ ​<code>​Point {​</code>​

​<code>​var x = 0.0, y = 0.0​</code>​

​<code>​struct​</code>​ ​<code>​Size {​</code>​

​<code>​var width = 0.0, height = 0.0​</code>​

​<code>​struct​</code>​ ​<code>​Rect {​</code>​

​<code>​var origin = Point()​</code>​

​<code>​var size = Size()​</code>​

​<code>​var center: Point {​</code>​

​<code>​get {​</code>​

​<code>​let centerX = origin.x + (size.width / 2)​</code>​

​<code>​let centerY = origin.y + (size.height / 2)​</code>​

​<code>​return​</code>​ ​<code>​Point(x: centerX, y: centerY)​</code>​

​<code>​set(newCenter) {​</code>​

​<code>​origin.x = newCenter.x - (size.width / 2)​</code>​

​<code>​origin.y = newCenter.y - (size.height / 2)​</code>​

​<code>​var square = Rect(origin: Point(x: 0.0, y: 0.0),size: Size(width: 10.0, height: 10.0))​</code>​

​<code>​//調用了center的get方法,計算了Point​</code>​

​<code>​let initialSquareCenter = square.center​</code>​

​<code>​//調用了center的set方法,origin被修改了​</code>​

​<code>​square.center = Point(x: 15.0, y: 15.0)​</code>​

​<code>​println(​</code>​​<code>​"square.origin is now at (\(square.origin.x), \(square.origin.y))"​</code>​​<code>​)​</code>​

​<code>​// origin現在是 (10.0, 10.0)​</code>​

set方法可以省略參數,省略時,預設用newValue代替,如下:

​<code>​struct​</code>​ ​<code>​AlternativeRect {​</code>​

​<code>​set {​</code>​

​<code>​origin.x = newValue.x - (size.width / 2)​</code>​

​<code>​origin.y = newValue.y - (size.height / 2)​</code>​

隻有get方法的計算屬性是隻讀的,可以省略get,文法如下:

​<code>​struct​</code>​ ​<code>​Cuboid {​</code>​

​<code>​var width = 0.0, height = 0.0, depth = 0.0​</code>​

​<code>​var volume: Double {​</code>​

​<code>​return​</code>​ ​<code>​width * height * depth​</code>​

​<code>​let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)​</code>​

​<code>​println(​</code>​​<code>​"the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)"​</code>​​<code>​)​</code>​

​<code>​// 列印"the volume of fourByFiveByTwo is 40.0"​</code>​

屬性螢幕,允許開發者在設定變量值前後執行一段代碼

​<code>​class​</code>​ ​<code>​StepCounter {​</code>​

​<code>​var totalSteps: Int = 0 {​</code>​

​<code>​willSet(newTotalSteps) {​</code>​

​<code>​println(​</code>​​<code>​"About to set totalSteps to \(newTotalSteps)"​</code>​​<code>​)​</code>​

​<code>​didSet {​</code>​

​<code>​//參數省略時,預設使用oldValue,willSet的參數也可省略,預設是newValue​</code>​

​<code>​//在didSet方法裡也可以修改本屬性的值,并且在次數的指派不調用willSet和didSet​</code>​

​<code>​if​</code>​ ​<code>​totalSteps &gt; oldValue  {​</code>​

​<code>​println(​</code>​​<code>​"Added \(totalSteps - oldValue) steps"​</code>​​<code>​)​</code>​

​<code>​let stepCounter = StepCounter()​</code>​

​<code>​//每設定一次totalSteps 的值,都執行willSet和didSet各一次,初始化時都不執行​</code>​

​<code>​stepCounter.totalSteps = 200​</code>​

​<code>​// About to set totalSteps to 200​</code>​

​<code>​// Added 200 steps​</code>​

​<code>​stepCounter.totalSteps = 360​</code>​

​<code>​// About to set totalSteps to 360​</code>​

​<code>​// Added 160 steps​</code>​

​<code>​stepCounter.totalSteps = 896​</code>​

​<code>​// About to set totalSteps to 896​</code>​

​<code>​// Added 536 steps​</code>​

全局變量一般都是計算延遲的,類似延遲存儲變量, 但是不需要在前面加@lazy關鍵字

類型屬性就是屬于類型的屬性,想C++中靜态變量,隻存在一份,在所有類的執行個體中共享。

值類型(結構體和枚舉)可以定義存儲變量和計算變量的類型屬性,而指針類型(類)隻能定義計算變量的類型屬性

而存儲類型屬性可以是var和let型的,而計算類型屬性隻能是var型的

必須給存儲類型屬性賦初值,因為類型在初始化不能對存儲類型屬性指派

​<code>​//聲明類型屬性​</code>​

​<code>​struct​</code>​ ​<code>​SomeStructure {​</code>​

​<code>​static​</code>​ ​<code>​var storedTypeProperty = ​</code>​​<code>​"Some value."​</code>​

​<code>​static​</code>​ ​<code>​var computedTypeProperty: Int {​</code>​

​<code>​// return an Int value here​</code>​

​<code>​enum​</code>​ ​<code>​SomeEnumeration {​</code>​

​<code>​class​</code>​ ​<code>​SomeClass {​</code>​

​<code>​class​</code>​ ​<code>​var computedTypeProperty: Int {​</code>​

​<code>​//使用和指派類型屬性,使用類型調用類型屬性​</code>​

​<code>​println(SomeClass.computedTypeProperty)​</code>​

​<code>​println(SomeStructure.storedTypeProperty)​</code>​

​<code>​// 列印 "Some value."​</code>​

​<code>​SomeStructure.storedTypeProperty = ​</code>​​<code>​"Another value."​</code>​

​<code>​// 列印"Another value."​</code>​

下一篇: Realm Swift