屬性

  1. 屬性有存儲屬性,計算屬性
  2. 存儲屬性包括常量存儲屬性,變量存儲屬性
  3. 常量存儲屬性特性
    1. 若是一個值類型變量被聲明爲let,那麼這個變量下的全部都是常量不能夠改。
    2. 若是是一個引用類型被定義爲let,那麼這個類型下的常量不可改變,變量依然能夠改變。
struct Size {
    var a = 0
}

class React {
    var area = 0.0
}

let size = Size(a: 4)
size.a = 2

let react = React()
react.area = 3
react.area = 5
複製代碼
  1. 延時存儲屬性
    1. 當一個屬性加載大量數據,而且它可能用到,也可能用不到,這時候推薦使用延時存儲屬性
    2. 延時存儲屬性必定是var類型
class DataImport {
    var fileName = "file.txt"
}

class DataManger {
    lazy var importer = DataImport()
    var data = [String?]()
}

let dataManager = DataManger()
dataManager.data.append("one.txt")
dataManager.data.append("two.txt")

print(dataManager.importer.fileName)
複製代碼
  1. swift屬性沒有實例變量,它的變量就是屬性。
  2. 計算屬性
    1. 若是這個屬性是靠其餘屬性計算得來的,那麼這個屬性應該用計算屬性。
    2. 計算屬性要用var類型和延時存儲屬性同樣都用var。
    3. 以後寫好計算屬性名字後邊要寫上類型,以後大括號。
    4. 必需要有一個get方法,用來返回這個計算屬性的計算結果。
    5. 能夠有一個可選的set方法,該方法內部能夠用newValue來省略參數。
    6. 在用構造器初始化屬性時候,實際上是在初始化存儲屬性,計算屬性不用初始化,由於他能夠用存儲屬性計算得來。
    7. 在使用時候只要給相關的存儲屬性賦值後,計算屬性就能夠計算得來。
    8. 在使用時候只要給計算屬性賦值了,那麼就能夠得出新的存儲屬性.
struct Point {
    var x = 0.0, y = 0.0
}

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

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

var react = React(origin: Point(x: 0.0, y: 0.0), size: Size(width: 20, height: 10))
print(react.center)

react.center = Point(x: 30, y: 40)
print(react.origin)
複製代碼
  1. 只讀計算屬性
    1. 首先該屬性是用其餘存儲屬性計算獲得的,肯定該屬性是計算屬性。
    2. var name:type{}
    3. 肯定該計算屬性有沒有setter方法
    4. 若是沒有setter方法,那就是隻讀計算屬性,這時候能夠直接省略get關鍵字。
    5. 若是有seeter方法,那就是可讀寫計算屬性,get關鍵字不能夠省略,set能夠省略參數。
struct Cuboid {
    var width = 0.0, height = 0.9, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}

var cuboid = Cuboid(width: 10, height: 10, depth: 5)
print("volume: \(cuboid.volume)")

cuboid.width = 20
print("volume: \(cuboid.volume)")
複製代碼
  1. 屬性觀察器
    1. 若是要觀察計算屬性的賦值變化就添加set方法。
    2. 若是要觀察存儲屬性的賦值變化能夠用屬性觀察器。
    3. 因此通常屬性觀察器用在存儲屬性上。
    4. willSet能夠取到newValue,didSet能夠取到oldValue
class StepCounter {
    var totalStep = 0 {
        willSet{
            print("willSet --- 新值:\(newValue) 舊值:\(totalStep)")
        }
        
        
        didSet{
            print("didSet --- 新值:\(totalStep) 舊值:\(oldValue)")
        }
    }
}

var step = StepCounter()
step.totalStep = 100
step.totalStep = 300
step.totalStep = 800
//打印以下
//willSet --- 新值:100 舊值:0
//didSet --- 新值:100  舊值:0
//willSet --- 新值:300 舊值:100
//didSet --- 新值:300  舊值:100
//willSet --- 新值:800 舊值:300
//didSet --- 新值:800  舊值:300
複製代碼
  1. 屬性觀察器變量若是傳入一個inout類型函數的參數中,即便函數內部沒有操做。也會觸發屬性觀察器。
class StepCounter {
    var totalStep = 0 {
        willSet{
            print("willSet --- 新值:\(newValue) 舊值:\(totalStep)")
        }
        
        
        didSet{
            print("didSet --- 新值:\(totalStep) 舊值:\(oldValue)")
        }
    }
}

var step = StepCounter()
func test(a: inout Int){

}

test(a: &step.totalStep)
複製代碼
  1. 全局變量和局部變量
    1. 全局變量都是延時變量,用到時候纔會加載。
    2. 局部變量必定不是延時變量,也不容許寫lazy關鍵字。
    3. 類外就是全局變量。類內是屬性,方法閉包內部是局部變量。
//全局變量
var globleVar = 4.5

class Test {
    //屬性
    var a = 1
    init() {
        //局部變量
        var b = 2
    }
}
複製代碼
  1. 類型屬性
    1. 若是一個屬性被全部實例對象共享那就考慮用類型屬性
    2. 類型屬性關鍵字是static,它是用類訪問的變量。和類有關
    3. 實例屬性是實例訪問的屬性,和實例有關
struct AudioChannel {
    static let thresholdLevel = 10
    static var maxLevelForAllChannel = 0
    var curLevel = 0{
        didSet{
            if curLevel > AudioChannel.thresholdLevel {
                curLevel = AudioChannel.thresholdLevel
            }
            
            if curLevel > AudioChannel.maxLevelForAllChannel {
                AudioChannel.maxLevelForAllChannel = curLevel
            }
        }
    }
}

var leftAudioChannel = AudioChannel(curLevel: 0)
var rightAudioChannel = AudioChannel(curLevel: 0)
leftAudioChannel.curLevel = 2
print(AudioChannel.maxLevelForAllChannel)
rightAudioChannel.curLevel = 3
print(AudioChannel.maxLevelForAllChannel)
rightAudioChannel.curLevel = 13
print(AudioChannel.maxLevelForAllChannel)
複製代碼
  1. 總結
    1. 類外是全局變量 - 延時加載
    2. 類內是屬性
      1. 屬性包括實例屬性和類型屬性
        1. 存儲屬性
          1. 常量存儲屬性
          2. 變量存儲屬性
          3. 延時存儲屬性
          4. 屬性觀察器
        2. 計算屬性
    3. 函數閉包內部是局部變量 - 必定不是延時加載的,也不容許用lazy關鍵字
相關文章
相關標籤/搜索