美文网首页swift
《Swift从入门到精通》(七):属性

《Swift从入门到精通》(七):属性

作者: 萧1帅 | 来源:发表于2021-10-11 11:12 被阅读0次

    属性(学习笔记)

    环境Xcode 11.0 beta4 swift 5.1

    • 属性(Properties)

      • 属性是把值和特定的类、结构体、枚举关联在一起
      • 属性主要是分为存储属性(Stored Properties)和计算属性(Computed Properties)
      • 存储属性是用来存储实例的常量或者变量
      • 计算属性主要是用来计算值
      • 计算属性可以定义在类、结构体、枚举
      • 存储属性可以定义在类、结构体
    • 存储属性(Stored Properties)

      • 可以用varlet修饰,后者一旦初始化就不可更改

        struct FixedLengthRange {
            var firstValue: Int
            let length: Int
        }
        var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
        // the range represents integer values 0, 1, and 2
        rangeOfThreeItems.firstValue = 6
        // the range now represents integer values 6, 7, and 8
        
        
      • 结构体实例常量的存储属性,即被let修饰,此时的存储属性被var修饰了不能更改,因为结构体是值类型,结构体变量的存储属性的内存是存储在结构体变量的内存中的

        let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
        // this range represents integer values 0, 1, 2, and 3
        rangeOfFourItems.firstValue = 6
        // this will report an error, even though firstValue is a variable property
        
        
      • 延迟存储属性(Lazy Stored Properties),用lazy来标识且只能申明为var,延迟存储属性是第一用到才赋值,而let修饰的属性要在初始化前就要有值

        // 以下示例代码类不是完整的类
        class DataImporter {
            /*
            DataImporter is a class to import data from an external file.
            The class is assumed to take a nontrivial amount of time to initialize.
            */
            var filename = "data.txt"
            // the DataImporter class would provide data importing functionality here
        }
        class DataManager {
            lazy var importer = DataImporter()
            var data = [String]()
            // the DataManager class would provide data management functionality here
        }
        let manager = DataManager()
        manager.data.append("Some data")
        manager.data.append("Some more data")
        // the DataImporter instance for the importer property has not yet been created
        print(manager.importer.filename)
        // the DataImporter instance for the importer property has now been created
        // Prints "data.txt"
        
        
      • 存储属性&实例变量,在OC中有两种方式存储值和类的实例对象,即属性和实例变量(即成员变量);Swift统一了这些概念,属性的所有信息(包括它的名称、类型和内存管理特性)都在类型定义的时候,作为类型的一部分定义在类型中

    • 计算属性(Computed Properties)

      • 计算属性不是真的用来存储值,而是提供gettersetter(可选)去获取和设置其它属性和值

        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))")
        // Prints "square.origin is now at (10.0, 10.0)"
        
        
      • 简写的setter声明(内部有一个默认的变量名newValue

        struct AlternativeRect {
            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)
                }
            }
        }
        
        
      • 简写的getter声明(隐式返回即省略return)

        struct CompactRect {
            var origin = Point()
            var size = Size()
            var center: Point {
                get {
                    Point(x: origin.x + (size.width / 2),
                          y: origin.y + (size.height / 2))
                }
                set {
                    origin.x = newValue.x - (size.width / 2)
                    origin.y = newValue.y - (size.height / 2)
                }
            }
        }
        
        
      • 只读计算属性(Read-Only Computed Properties),只有getter,没有setter,可以用var修饰,getter也可以省略不写

        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)")
        // Prints "the volume of fourByFiveByTwo is 40.0"
        
        
    • 属性观察器(Property Observers)

      • 观察和响应属性值的变化,即使设置的是相同的值也会触发;

      • 可以为任意的属性添加属性观察器,延迟存储属性除外

      • 可以在子类为任意继承属性(存储或计算属性)添加属性观察器

      • 非重写的计算属性不需要定义属性观察器,可以在setter中观察和响应

      • 可以在属性上添加willSet(在值存储前调用,自带一个常量参数newValuedidSet(新设置的值存储立即调用,自带一个常量参数oldValue

        class StepCounter {
            var totalSteps: Int = 0 {
                willSet(newTotalSteps) { // 不用默认的newValue,自定义一个参数
                    print("About to set totalSteps to \(newTotalSteps)")
                }
                didSet {
                    if totalSteps > oldValue  {
                        print("Added \(totalSteps - oldValue) steps")
                    }
                }
            }
        }
        let stepCounter = StepCounter()
        stepCounter.totalSteps = 200
        // About to set totalSteps to 200
        // Added 200 steps
        stepCounter.totalSteps = 360
        // About to set totalSteps to 360
        // Added 160 steps
        stepCounter.totalSteps = 896
        // About to set totalSteps to 896
        // Added 536 steps
        
        
      • 传递一个属性给一个in-out 参数,willSet didSet 都会被调用,这是因为in-out参数的copy-in copy-out 内存管理,在函数调用的最后总是会将值写加给属性

    • 全局和局部变量(Global and Local Variables)

      • 全局和局部变量都可以设置计算属性和属性观察器
      • 全局常量和变量总是延迟计算,类似延迟存储属性,但不需要lazy修饰
      • 局部常量和变量从不是延迟计算的
    • 类型属性(Type Properties)

      • 是线程安全的

      • 计算类型属性总是变量(同计算实例属性)和存储类型属性可以是变量或常量

      • static 关键字修饰,由class定义的类可以用class关键字标识类型属性,以便子类重写

        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
            }
        }
        // 以上示例代码是定义成只读属性,也可以定义成可读可写属性
        
        

    相关文章

      网友评论

        本文标题:《Swift从入门到精通》(七):属性

        本文链接:https://www.haomeiwen.com/subject/rdixoltx.html