欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

属性

程序员文章站 2022-03-01 21:17:57
...
  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关键字