美文网首页
Swift中的属性

Swift中的属性

作者: 落叶刺客 | 来源:发表于2017-05-24 15:21 被阅读30次

  我们都知道,类是由属性和方法组成的,一般而言,属性主要是用来访问数据成员,而方法则是用来执行某些操作,比如说计算数据等等。在Objective-C中,属性主要是用来访问封装之后的数据成员,属性本身并不存储数据,数据是由数据成员来存储。但是在Swift中,属性承担了多种角色,它远比Objective-C中的属性更为强大。

  Swift中的属性可以分为存储属性和计算属性,其中存储属性就相当于Objective-C中的数据成员,主要是用来存储数据;而计算属性则可以通过计算其它属性的值来返回数据。下面我们来对它们做一个了解。

  1、存储属性

  Swift中的存储属性在形式上和普通的常量、变量并无不同。一般而言,属性在类被初始化的时候也要被初始化,否则就应该将其声明为可选类型。比如说:

class Student {
    
    // 存储属性
    var name: String?  // 声明为可选类型
    var age: Int = 0  // 初始化为默认值
    var sex: String = "Female"
    var height: Double = 0.0
}

let p = Student()
p.name = "LeBron James"
p.age = 33
p.sex = "Male"
p.height = 2.03

  出于性能方面的考虑,有时候我们并不希望一个属性在被使用之前就被加载进内存,对于这种情况,我们可以使用关键字lazy来修饰:

class Student {
    
    // 存储属性
    var name: String?  
    
    // 延迟加载属性
    lazy var dog: Dog = Dog()
}

struct Dog {
    var name: String?
    var age: Int = 0
}

// 实例化Student类
let p = Student()
p.name = "LeBron James"
// 用到dog属性时,它才会被加载
p.dog.name = "WangCai"

  假如我们没有用关键字lazy对Student类的dog属性进行修饰,那么当我们创建p实例的时候,它也会被实例化并被加载进内存。而使用lazy进行修饰之后,只有当我们用到它时,它才会被加载。另外,一定要注意,存储属性只适用于类和结构体这两种类型,并不适用于枚举

  2、计算属性

  计算属性本身并不会存储数据,而是从其它存储属性中计算得到数据。计算属性不仅可以用于类和结构体,还可以用于枚举。计算属性的格式为:

class(struct/enum) 类型名 {
    存储属性
    
    var 计算属性名: 属性数据类型 {
        get {
            return 计算完成后属性的值
        }
        
        set(新属性的值) {
            // 其它代码
        }
    }
}

  计算属性中提供一个get用来获取值,另外一个set用来设置其它属性或变量的值,其中set方法是可选的。另外,计算属性应该使用var来修饰。

  3、只读计算属性

  计算属性可以只有get访问器,而没有set访问器,像这种计算属性就是只读计算属性。只读计算属性还可以直接省略掉关键字get及其后面的花括号,直接返回计算后的值。只读计算属性在实际开发过程经常会用到,比如说设置导航控制器顶部状态栏的颜色:

// 重写父类状态栏管理的属性(这是一个只读的计算属性,可以省略get{},直接return就可以了)
override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

  4、属性监听器

  为了监听属性的变化,Swift中提供了属性监听器。属性监听器能够及时的监听存储属性的变化,即便是存储属性变化前后的值相同,它也能够监听到。但是,一定要注意,属性监听器并不能监听延迟存储属性(也就是用lazy修饰的存储属性)和常量属性的变化。

  属性监听器中有两个重要的关键字,分别是willSet和didSet。其中,willSet在属性监听器修改之前调用,而didSet在属性监听器修改之后调用。属性监听器的格式为:

class(struct) 类型名 {
    其它存储属性
    
    var 存储属性名: 存储属性的数据类型 = 初始化值 {
        willSet(新值) {
            // 代码
        }
        
        didSet(旧值) {
            // 代码
        }
    }
}

  注意,因为枚举不支持存储属性,所以属性监听器并不能在枚举中使用。下面,我们看一个具体的示例:

// 属性监听器
class Person {
    var age: Int = 0
    var name: String = "Enrica" {
        willSet(newValue) {
            print("变量name的新值:\(newValue)")
        }
        
        didSet(oldValue) {
            print("变量name的旧值:\(oldValue)")
        }
    }
    
    var height: Double = 0
}

var p = Person()
p.age = 10

// 属性监听器一旦监听到name值的改变,就会调用willSet和didSet方法
p.name = "LeBron"

  在上面的Person类中,存储属性name有一个默认的值“Enrica”,当我们使用p.name = "LeBron"重新给它赋值时,属性监听器立马就能监听到,然后做出相应的反映。另外,其实willSet和didSet后面小括号中的参数是可以省略的,系统会给它们分配一个默认的参数。比如说,上面的代码可以修改为:

// 属性监听器
class Person {
    var age: Int = 0
    var name: String = "Enrica" {
        willSet {
            print("变量name的新值:\(newValue)")
        }
        
        didSet {
            print("变量name的旧值:\(oldValue)")
        }
    }
    
    var height: Double = 0
}

var p = Person()
p.age = 10

// 属性监听器一旦监听到name值的改变,就会调用willSet和didSet方法
p.name = "LeBron"

  代码修改之后,运行的结果一毛一样。属性监听器看起来很麻烦,但是实际应用非常的广泛,所以一定要掌握。

相关文章

  • OC的@property与Swift的存储属性/计算属性类比

    Swift中的计算属性/存储属性与OC中的@property   Swift中引入了存储属性、计算属性的概念,存储...

  • Swift 属性

    Swift 属性 在Swift中属性主要分为存储属性、计算属性、延迟存储属性、类型属性这四种,并且Swift还提供...

  • Swift进阶(三)--- 属性

    Swift的属性 在swift中,属性主要分为以下几种: 存储属性 计算属性 延迟存储属性 类型属性 一:存储属性...

  • 浅谈 Swift 中的属性(Property)

    Properties in Swift 前言 Swift 中的属性分为存储属性与计算属性,存储属性即为我们平时常用...

  • 第10章:属性

      在Swift中枚举、结构体、类都可以有属性,属性描述了类型的某个特性。在Swift中属性从大的方面分可以分为存...

  • Swift学习-进阶02

    swift对象本质,一个swift的对象默认占用16字节大小,在内存中的结构: swift类结构: 属性 存储属性...

  • Swift 计算属性、存储属性

    属性 Swift中的属性分为存储属性(sorted variable)和计算型属性(computed variab...

  • Swift中的属性

    1. 存储属性 简单来说,每一个存储属性就是存储在特定类或结构体实例里的一个常量或变量。存储属性可以使变量存储属性...

  • Swift中的属性

      我们都知道,类是由属性和方法组成的,一般而言,属性主要是用来访问数据成员,而方法则是用来执行某些操作,比如说计...

  • swift中的属性

    属性可以将值与特定的类、结构体或者是枚举联系起来。 一、简介 存储属性与计算属性的差异: 存储属性会存储敞亮或者变...

网友评论

      本文标题:Swift中的属性

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