SwiftProperty Swift3.0 屬性

Swift Peoperty

Swift中有下列幾種屬性

  1. 存儲(chǔ)屬性(Stored properties):存儲(chǔ)實(shí)例的常量和變量,與類、結(jié)構(gòu)體、枚舉的實(shí)例相關(guān)
  2. 計(jì)算屬性(Computed properties):通過(guò)某種方式計(jì)算出來(lái)的屬性,只與類、結(jié)構(gòu)體的實(shí)例相關(guān),枚舉沒(méi)有計(jì)算屬性
  3. 類型屬性(type properties):與類型自身相關(guān)

存儲(chǔ)屬性

存儲(chǔ)屬性是最簡(jiǎn)單的屬性,它作為類或結(jié)構(gòu)體實(shí)例的一部分,用于存儲(chǔ)常量和變量

關(guān)于存儲(chǔ)屬性,有以下幾點(diǎn):

  1. 我們可以給存儲(chǔ)屬性提供一個(gè)默認(rèn)值,也可以在初始化方法中對(duì)其進(jìn)行初始化,即使是常量型屬性,也可以這樣做。
  2. 如果創(chuàng)建一個(gè)常量結(jié)構(gòu)體實(shí)例,我們不能修改該實(shí)例的變量型存儲(chǔ)屬性。這是因?yàn)榻Y(jié)構(gòu)體是值類型,當(dāng)一個(gè)值類型的實(shí)例標(biāo)記為常量時(shí),它的所有屬性也是常量。由于類是引用類型,所以該條不適用于類類型。
  3. 如果我們希望屬性在使用到的時(shí)候再初始化,則可以使用懶惰存儲(chǔ)屬性(lazy stored property,使用修飾符@lazy)。懶惰存儲(chǔ)屬性總是應(yīng)該定義為變量,因?yàn)槌A啃蛯傩钥傂枰诔跏蓟椒ㄍ瓿芍俺跏蓟?/li>
  4. 與Objective-C不同的是,Swift中的屬性不需要一個(gè)與之對(duì)應(yīng)的成員變量,我們不能直接訪問(wèn)屬性的后備存儲(chǔ)(backing store)。這種方式避免了混淆不同上下文環(huán)境下對(duì)值的訪問(wèn),并將屬性簡(jiǎn)化為單一、明確的聲明。
struct FixedLengthRange {
  var firstValue: Int   //變量存儲(chǔ)屬性
  let length: Int       //常量存儲(chǔ)屬性
}

var item1 = FixedLengthRange(firstValue: 10, length: 10)
    
let item2 = FixedLengthRange(firstValue: 10, length: 10)

//item2.firstValue = 6       // 錯(cuò)誤:不能修改常量結(jié)構(gòu)體實(shí)例的存儲(chǔ)屬性

計(jì)算屬性

計(jì)算屬性并不存儲(chǔ)實(shí)際的值,而是提供一個(gè)getter和一個(gè)可選的[ setter來(lái)間接獲取和設(shè)置其它屬性 ]。

關(guān)于計(jì)算屬性,有以下幾點(diǎn):

  1. 如果計(jì)算屬性的setter沒(méi)有定義一個(gè)新值的變量名,則默認(rèn)為newValue
  2. 如果只提供getter,而不提供setter,則該計(jì)算屬性為只讀屬性
  3. 我們只能聲明變量型只讀屬性,因?yàn)樗鼈兊闹挡皇枪潭ǖ?/li>
  4. 如果計(jì)算屬性是只讀的,則可以不使用get{}
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 {          // 計(jì)算屬性
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {            // 若不提供新值變量名,則默認(rèn)為newValue
            origin.x = newCenter.x - size.width / 2
            origin.y = newCenter.y - size.height / 2
        }
    }
    
    var maxX:Float {        // 只讀屬性,省略get{}
        return Float(origin.x) + Float(size.width)
    }
}
    
var square = Rect(origin:Point(x: 0.0, y: 0.0), size:Size(width:100, height:100))
    
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y:15.0)
square.maxX

類型屬性

類型屬性是與類型相關(guān)聯(lián)的,而不是與類型的實(shí)例相關(guān)聯(lián)?!?與類型相關(guān)不與對(duì)象相關(guān)對(duì)于某一類型(class)的所有實(shí)例,類型(class)屬性都只有一份拷貝。對(duì)于值類型(struct),我們可以定義存儲(chǔ)類型屬性和計(jì)算類型屬性。對(duì)于類(class),我們只能定義計(jì)算類型(setter)屬性。和實(shí)例屬性不同的是,我們總是需要給存儲(chǔ)類型(getter)屬性一個(gè)默認(rèn)值。這是因?yàn)轭愋蜎](méi)有初始化方法來(lái)初始化類型屬性。

類型屬性的訪問(wèn)和設(shè)置與實(shí)例屬性一樣,不一樣的是,類型屬性通過(guò)類型來(lái)獲取和設(shè)置,而不是類型的實(shí)例

關(guān)鍵字 : class static

struct AudioChannel {
    static let threaholdLevel = 10
    static var maxInputLevelForAllChannels = 0
    
    var currentLevel:Int = 0 {
        didSet{
            if currentLevel > AudioChannel.threaholdLevel {
                currentLevel = AudioChannel.threaholdLevel
            }
            
            if currentLevel > AudioChannel.maxInputLevelForAllChannels {
                AudioChannel.maxInputLevelForAllChannels = currentLevel
            }
        }
    }
}
    
var leftChannel = AudioChannel()
var rightChannel = AudioChannel()
    
leftChannel.currentLevel = 7
    
println(leftChannel.currentLevel)       // 7
println(AudioChannel.maxInputLevelForAllChannels)   // 7
    
rightChannel.currentLevel = 11
println(rightChannel.currentLevel)      // 10

屬性觀察者

屬性觀察者用于監(jiān)聽(tīng)和響應(yīng)屬性值的變化。在每次設(shè)置屬性值的時(shí)候都會(huì)調(diào)用屬性觀察者方法,即使新舊值是一樣的。我們可以為任何存儲(chǔ)屬性定義屬性觀察者,除了懶惰存儲(chǔ)屬性。我們同樣可以在子類中給繼承而來(lái)的屬性添加觀察者。

對(duì)于計(jì)算屬性,我們不需要定義屬性觀察者,因?yàn)槲覀兛梢栽谟?jì)算屬性的setter中直接觀察并響應(yīng)這種值的變化。

我們通過(guò)設(shè)置以下觀察方法來(lái)定義觀察者

  1. willSet:在屬性值被存儲(chǔ)之前設(shè)置。此時(shí)新屬性值作為一個(gè)常量參數(shù)被傳入。該參數(shù)名默認(rèn)為newValue,我們可以自己定義該參數(shù)名
  2. 在新屬性值被存儲(chǔ)后立即調(diào)用。與willSet相同,此時(shí)傳入的是屬性的舊值,默認(rèn)參數(shù)名為oldValue

willSet與didSet只有在屬性第一次被設(shè)置時(shí)才會(huì)調(diào)用,在初始化時(shí),不會(huì)去調(diào)用這些監(jiān)聽(tīng)方法。

轉(zhuǎn)載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容