Swift - 属性

  • 简述

    Swift 4 语言为类、枚举或结构提供属性来关联值。属性可以进一步分为存储属性和计算属性。
    存储属性和计算属性的区别
    存储属性 计算属性
    将常量和变量值存储为实例 计算一个值而不是存储该值
    由类和结构提供 由类、枚举和结构提供
    Stored 和 Computed 属性都与实例类型相关联。当属性与其类型值相关联时,它被定义为“类型属性”。存储和计算属性通常与特定类型的实例相关联。但是,属性也可以与类型本身相关联。此类属性称为类型属性。还使用了属性观察器
    • 观察存储属性的值
    • 观察从超类派生的继承子类的属性
  • 存储属性

    Swift 4 引入了存储属性的概念来存储常量和变量的实例。常量的存储属性由“let”关键字定义,变量的存储属性由“var”关键字定义。
    • 在定义期间存储的属性提供“默认值”
    • 在初始化期间,用户可以初始化和修改初始值
    
    struct Number {
       var digits: Int
       let pi = 3.1415
    }
    var n = Number(digits: 12345)
    n.digits = 67
    print("\(n.digits)")
    print("\(n.pi)")
    
    当我们使用操场运行上述程序时,我们得到以下结果 -
    
    67
    3.1415
    
    考虑上面代码中的以下行 -
    
    let pi = 3.1415
    
    这里,变量 pi 被初始化为一个存储的属性值,实例 pi = 3.1415。因此,无论何时引用实例,它都会单独保存值 3.1415。
    另一种存储属性的方法是使用常量结构。因此,结构的整个实例将被视为“常量的存储属性”。
    
    struct Number {
       var digits: Int
       let numbers = 3.1415
    }
    var n = Number(digits: 12345)
    n.digits = 67
    print("\(n.digits)")
    print("\(n.numbers)")
    n.numbers = 8.7
    
    当我们使用操场运行上述程序时,我们得到以下结果 -
    
    error: cannot assign to 'numbers' in 'n'
    n.numbers = 8.7
    
    它不会将“数字”重新初始化为 8.7,而是会返回一条错误消息,指出“数字”已声明为常量。
  • 惰性存储属性

    Swift 4 提供了一个名为“Lazy Stored Property”的灵活属性,当变量第一次初始化时,它不会计算初始值。'lazy' 修饰符在变量声明之前使用,以将其作为惰性存储属性。
    使用惰性属性 -
    • 延迟对象创建。
    • 当属性依赖于类的其他部分时,这些部分尚不清楚
    
    class sample {
       lazy var no = number()    // `var` declaration is required.
    }
    class number {
       var name = "Swift 4"
    }
    var firstsample = sample()
    print(firstsample.no.name)
    
    当我们使用操场运行上述程序时,我们得到以下结果 -
    
    Swift 4
    
  • 实例变量

    在 Objective C 中,存储属性也有实例变量用于备份目的,以存储存储属性中声明的值。
    Swift 4 将这两个概念集成到一个“存储属性”声明中。“存储属性”没有相应的实例变量和备份值,而是包含通过变量名称、数据类型和内存管理功能在单个位置定义的关于变量属性的所有集成信息。
  • 计算属性

    计算属性提供了一个 getter 和一个可选的 setter 来间接检索和设置其他属性和值,而不是存储值。
    
    class sample {
       var no1 = 0.0, no2 = 0.0
       var length = 300.0, breadth = 150.0
       var middle: (Double, Double) {
          get {
             return (length / 2, breadth / 2)
          }
          
          set(axis){
             no1 = axis.0 - (length / 2)
             no2 = axis.1 - (breadth / 2)
          }
       }
    }
    var result = sample()
    print(result.middle)
    result.middle = (0.0, 10.0)
    print(result.no1)
    print(result.no2)
    
    当我们使用操场运行上述程序时,我们得到以下结果 -
    
    (150.0, 75.0)
    -150.0
    -65.0
    
    当计算属性将新值保留为未定义时,将为该特定变量设置默认值。

    作为只读属性的计算属性

    计算属性中的只读属性定义为具有 getter 但没有 setter 的属性。它总是用于返回一个值。变量可以通过“.”进一步访问。语法但不能设置为其他值。
    
    class film {
       var head = ""
       var duration = 0.0
       var metaInfo: [String:String] {
          return [
             "head": self.head,
             "duration":"\(self.duration)"
          ]
       }
    }
    var movie = film()
    movie.head = "Swift 4 Properties"
    movie.duration = 3.09
    print(movie.metaInfo["head"]!)
    print(movie.metaInfo["duration"]!)
    
    当我们使用操场运行上述程序时,我们得到以下结果 -
    
    Swift 4 Properties
    3.09
    

    作为属性观察者的计算属性

    在 Swift 4 中,使用 Property Observers 来观察和响应属性值。每次设置属性值时,都会调用属性观察器。除了惰性存储属性,我们可以通过“覆盖”方法将属性观察器添加到“继承”属性。
    属性观察者可以通过以下任一方式定义
    • 在存储值之前 - willset
    • 存储新值后 - didset
    • 当在初始化器中设置属性时,不能调用 willset 和 didset 观察者。
    
    class Samplepgm {
       var counter: Int = 0 {
          willSet(newTotal){
             print("Total Counter is: \(newTotal)")
          }
          
          didSet {
             if counter > oldValue {
                print("Newly Added Counter \(counter - oldValue)")
             }
          }
       }
    }
    let NewCounter = Samplepgm()
    NewCounter.counter = 100
    NewCounter.counter = 800
    
    当我们使用操场运行上述程序时,我们得到以下结果 -
    
    Total Counter is: 100
    Newly Added Counter 100
    Total Counter is: 800
    Newly Added Counter 700
    
  • 局部和全局变量

    声明局部和全局变量用于计算和观察属性。
    局部变量 全局变量
    在函数、方法或闭包上下文中定义的变量。 在函数、方法、闭包或类型上下文之外定义的变量。
    用于存储和检索值。 用于存储和检索值。
    存储的属性用于获取和设置值。 存储的属性用于获取和设置值。
    还使用计算属性。 还使用计算属性。
  • 类型属性

    属性在类型定义部分用花括号 {} 定义,变量的范围也在前面定义。为了定义值类型的类型属性,使用“static”关键字,而对于类类型,使用“class”关键字。

    句法

    
    struct Structname {
       static var storedTypeProperty = " "
       static var computedTypeProperty: Int {
          // return an Int value here
       }
    }
    enum Enumname {
       static var storedTypeProperty = " "
       static var computedTypeProperty: Int {
          // return an Int value here
       }
    }
    class Classname {
       class var computedTypeProperty: Int {
          // return an Int value here
       }
    }
    
  • 查询和设置属性

    就像实例属性一样,类型属性被查询并用“.”设置。语法只针对类型而不是指向实例。
    
    struct StudMarks {
       static let markCount = 97
       static var totalCount = 0
       
       var InternalMarks: Int = 0 {
          didSet {
             if InternalMarks > StudMarks.markCount {
                InternalMarks = StudMarks.markCount
             }
             if InternalMarks > StudMarks.totalCount {
                StudMarks.totalCount = InternalMarks
             }
          }
       }
    }
    var stud1Mark1 = StudMarks()
    var stud1Mark2 = StudMarks()
    stud1Mark1.InternalMarks = 98
    print(stud1Mark1.InternalMarks)
    stud1Mark2.InternalMarks = 87
    print(stud1Mark2.InternalMarks)
    
    当我们使用操场运行上述程序时,我们得到以下结果 -
    
    97
    87