swift

Swift Properties

2018-04-12  本文已影响10人  mkvege

参考自苹果官网Swift文档 原文地址

类,枚举,结构体都具有属性
属性的种类,存储属性,计算属性,类型属性
  1. 存储属性
    OC中的属性基本都可以称为存储属性,也是使用最广泛的属性,用于记录一个实例的属性的值
  2. 计算属性,下面是来自于官网的例子
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)
        }
    }
}

Rect 中的center 属性不存在于内存当中,每次获取这个center值走get方法 通过 origin 和 size 属性计算出来。同理,每次设置center 时也会通过set方法更新origin属性的值

不同于OC中的set,get方法,swift 的 set,get 方法用于计算属性的实现中,其中set方法不是必要的

  1. 类型属性
    类似于OC 中的类方法,每个类,结构体,枚举都可以有自己的类属性。例如下面的 SomeStructure.computedTypeProperty。可以用于定义一些不需要实例化的属性。属性前用 static 修饰即为类属性。
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
    }
}
属性的懒加载

OC 中一般使用重写get 方法来实现懒加载,Swift中需要在属性定义前加一个 lazy 关键字,例如

class DataManager {
    lazy var importer = DataImporter()
}

DataManager 中的importer属性在最开始就 调用了DataImporter()初始化方法,但是关键字lazy 使其不会在一开始进入初始化方法,而是在首次调用importer 属性时才会进入初始化方法。
当然懒加载 lazy 关键字只用于 存储类型的属性

只读属性

OC 中的readonly 属性,在swift 中的写法如下

struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}

直接大括号 return 掉

属性的监听

OC 中的经常重写set方法用于控制新的属性值,以及更新UI等,Swift 中可以通过实现属性的willset,didset 方法来实现,如下:

class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}

willSet 在属性totalSteps修改前调用
didSet 在修改后使用,如果didSet 后不加括号,则oldValue 为默认传入的旧属性值的字段。
注意:控制属性值的话需通过实现didset 方法,而不是willSet方法,例如:

var computeProperty :Int = 0{
        didSet (oldCompute) {
            print("old value \(oldCompute)")
            if computeProperty > 10 {
                computeProperty = 10
            }
        }
    }

Swift中如果使用KVO,会显得有些奇怪。因为KVO 通过OC runtime实现,只支持NSObject 及其子类,所以如果要在Swift中使用,要在属性前加入 @objc dynamic 关键字。例如:

 @objc dynamic  var computeProperty :Int = 0{
   
 }
属性的内存管理

同OC一样,如果要弱引用在属性前加 weak 关键字,如果是闭包需根据情况使用 unowned 关键字

上一篇下一篇

猜你喜欢

热点阅读