Swift4 基礎(chǔ)部分: Properties

本文是學習《The Swift Programming Language》整理的相關(guān)隨筆,基本的語法不作介紹,主要介紹Swift中的一些特性或者與OC差異點。

系列文章:

常量的結(jié)構(gòu)體實例的屬性(Stored Properties of Constant Structure Instances)

If you create an instance of a structure and assign that 
instance to a constant, you cannot modify the instance’s 
properties, even if they were declared as variable 
properties:
  • 常量的結(jié)構(gòu)體實例的屬性即使是var修飾也不能更改它的值

例子:

struct FixedLengthRange{
    var firstValue:Int
    let length:Int
}

let rangeOfFourItems = FixedLengthRange(firstValue:0,length:4)
rangeOfFourItems.firstValue = 6;

編譯錯誤:

error: MyPlayground.playground:527:29: error: cannot assign to property: 'rangeOfFourItems' is a 'let' constant
rangeOfFourItems.firstValue = 6;
~~~~~~~~~~~~~~~~            ^

MyPlayground.playground:526:1: note: change 'let' to 'var' to make it mutable
let rangeOfFourItems = FixedLengthRange(firstValue:0,length:4)
^~~

原因:

Because rangeOfFourItems is declared as a constant (with 
the let keyword), it is not possible to change its 
firstValue property, even though firstValue is a variable 
property.

This behavior is due to structures being value types. When 
an instance of a value type is marked as a constant, so 
are all of its properties.
  • 如果一個結(jié)構(gòu)體實例被constant修飾,它的所有屬性也是默認的常量

延遲存儲屬性(Lazy Stored Properties)

A lazy stored property is a property whose initial value 
is not calculated until the first time it is used. You 
indicate a lazy stored property by writing the lazy 
modifier before its declaration.
  • 延遲存儲屬性只有當使用時才會被創(chuàng)建,用lazy關(guān)鍵字修飾

例子:

class DataImporter{
    var filename = "data.txt"
}

class DataManager{
    lazy var importer = DataImporter()
    var data = [String]()
}

let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
print(manager.importer.filename)

執(zhí)行結(jié)果:

someVideoMode === otherVideoMode
someVideoMode !== thirdVideoMode
data.txt

計算屬性(Computed Properties)

In addition to stored properties, classes, structures, and 
enumerations can define computed properties, which do not 
actually store a value. Instead, they provide a getter and 
an optional setter to retrieve and set other properties 
and values indirectly.
  • 除了存儲屬性,類與結(jié)構(gòu)體,枚舉都可以定義計算屬性,計算屬性是一個可選的setter來間接設(shè)置其他屬性或變量的值

例子:

struct Point{
    var x = 0.0,y = 0.0
}

struct Size{
    var width = 0.0,height = 0.0
}

struct Rect {
    var origin = Point()
    var size = Size()
    
    var center: Point{
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x:centerX,y:centerY)
        }
        
        set(newCenter){
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
    }
}

var square = Rect(origin: Point(x: 0.0, y: 0.0),
                     size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")

執(zhí)行結(jié)果:

square.origin is now at (10.0, 10.0)

便捷的Setter聲明(Shorthand Setter Declaration)

If a computed property’s setter does not define a name for 
the new value to be set, a default name of newValue is 
used. Here’s an alternative version of the Rect structure, 
which takes advantage of this shorthand notation:
  • 如果一個計算屬性的的set方法沒有定義一個新的名字給這個新的值,那么默認的名字就是newValue

例子:

struct Rect {
    var origin = Point()
    var size = Size()
    
    var center: Point{
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x:centerX,y:centerY)
        }
        
        set{
            origin.x = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
    }
}

只讀的計算屬性(Read-Only Computed Properties)

A computed property with a getter but no setter is known 
as a read-only computed property. A read-only computed 
property always returns a value, and can be accessed 
through dot syntax, but cannot be set to a different 
value.
  • 計算屬性如果只寫入了get方法沒有set方法,那么就是只讀的計算屬性

例子:

struct Cuboid{
   var width = 0.0, height = 0.0, depth = 0.0
   var volume: Double{
       return width * height * depth
   }
}

let fourByFiveByTwo = Cuboid(width:4.0,height:5.0,depth:2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")

例子:

the volume of fourByFiveByTwo is 40.0

屬性觀察器(Property Observers)

Property observers observe and respond to changes in a 
property’s value. Property observers are called every 
time a property’s value is set, even if the new value is 
the same as the property’s current value.

You can add property observers to any stored properties 
you define, except for lazy stored properties. You can 
also add property observers to any inherited property 
(whether stored or computed) by overriding the property 
within a subclass. You don’t need to define property 
observers for nonoverridden computed properties, because 
you can observe and respond to changes to their value in 
the computed property’s setter. Property overriding is 
described in Overriding.

You have the option to define either or both of these 
observers on a property:

- willSet is called just before the value is stored.
- didSet is called immediately after the new value is 
stored. 
  • 當屬性發(fā)生變化時會觸發(fā)屬性觀察器,可以給除了延遲存儲屬性的屬性添加觀察器。同樣子類繼承的屬性一樣也可以添加觀察器,只需要子類中重載屬性即可。
  • willSet當屬性將要變化是觸發(fā)
  • didSet當屬性已經(jīng)發(fā)生變化時觸發(fā)

例子:

 class StepCounter{
    var totalSteps:Int = 0{
        willSet(newTotalSteps){
            print("About to set totalSteps to \(newTotalSteps)")
        }
        
        didSet{
            if totalSteps > oldValue{
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}

let stepCounter = StepCounter()
stepCounter.totalSteps = 10
stepCounter.totalSteps = 20

執(zhí)行結(jié)果:

About to set totalSteps to 10
Added 10 steps
About to set totalSteps to 20
Added 10 steps

全局變量與局部變量(Global and Local Variables)

Global variables are variables that are defined outside of 
any function, method, closure, or type context. Local 
variables are variables that are defined within a function, 
method, or closure context.
  • 全局變量是在函數(shù)、方法、閉包或任何類型之外定義的變量,局部變量是在函數(shù)、方法或閉包內(nèi)部定義的變量。

例子:

var globalNum = 0;
func changeNumToTen(){
    var localNum = 10;
    globalNum = 10;
    print("globalNum:\(globalNum) localNum:\(localNum)");
}

changeNumToTen();
globalNum = 20;
print("globalNum:\(globalNum)");

執(zhí)行結(jié)果:

globalNum:10 localNum:10
globalNum:20

類型屬性(Type Properties)

Instance properties are properties that belong to an instance 
of a particular type. Every time you create a new instance of 
that type, it has its own set of property values, separate 
from any other instance.

You can also define properties that belong to the type 
itself, not to any one instance of that type. There will only 
ever be one copy of these properties, no matter how many 
instances of that type you create. These kinds of properties 
are called type properties.
  • 類型本身可以定義屬性,不管有多少個實例,這些屬性只有唯一一份

類型屬性語法(Type Property Syntax)

You define type properties with the static keyword. For 
computed type properties for class types, you can use the 
class keyword instead to allow subclasses to override the 
superclass’s implementation. 
  • 使用關(guān)鍵字static來定義類型屬性,另外可以以使用關(guān)鍵字class來定義計算類型屬性,讓子類可以重寫該方法(使用static的計算屬性不能被重寫)

例子:

struct SomeStructure {
    static var storedTypeProperty = "Some value.";
    static var computedTypeProperty: Int {
        return 1;
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value.";
    static var computedTypeProperty: Int {
        return 6;
    }
}
class SomeClass {
    
    static var storedTypeProperty = "Some value";
    static var computedTypeProperty: Int {
        return 27;
    }
    class var overrideableComputedTypeProperty: Int {
        return 107;
    }
}

class SubSomeClass:SomeClass{
    override class var overrideableComputedTypeProperty: Int {
        return 108;
    }
}

print(SomeStructure.storedTypeProperty)
SomeStructure.storedTypeProperty = "Another value."
print(SomeStructure.storedTypeProperty)
print(SomeEnumeration.computedTypeProperty)
print(SomeClass.computedTypeProperty)
print(SomeClass.overrideableComputedTypeProperty)
print(SubSomeClass.overrideableComputedTypeProperty)

執(zhí)行結(jié)果:

Some value.
Another value.
6
27
107
108
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,954評論 6 342
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • Swift語法基礎(chǔ)(五)-- (類和結(jié)構(gòu)體、屬性、方法) 本章將會介紹 類和結(jié)構(gòu)體對比結(jié)構(gòu)體和枚舉是值類型類是引用...
    寒橋閱讀 1,102評論 0 1
  • 我每天使用 Git ,但是很多命令記不住。一般來說,日常使用只要記住下圖6個命令,就可以了。但是熟練使用,恐怕要記...
    Smallwolf_JS閱讀 349評論 0 2
  • 等你的日子緩慢悠長, 荷葉剛醒,晨光熹微。 我在等你, 你 不知道。 在街上徘徊, 想著此刻的你在哪? 該走哪條路...
    慎何閱讀 339評論 6 3