浅谈 Swift 中的属性(Property)

2018-04-23  本文已影响92人  枫叶1234

前言

Swift 中的属性分为存储属性与计算属性,存储属性即为我们平时常用的属性,可以直接赋值使用,而计算属性不直接存储值,而是根据其他(存储)属性计算得来的值。

在其他面向对象的编程语言中,例如 Java 和 Objective-C 中,get 和 set 方法提供了统一、规范的接口,可以使得外部访问或设置对象的私有属性,而不破坏封装性,也可以很好的控制权限(选择性实现 get 或 set 方法)。而 Swift 中似乎并没有见到类似的 get 和 set 方法,而 Swift 使用了一种名为属性观察器的概念来解决该问题。

本文简单介绍下 Swift 中的这两种属性,以及属性观察器。

延迟存储属性

存储属性使用广泛,即是类或结构体中的变量或常量,可以直接赋初始值,也可以修改其初始值(仅指变量)。

延迟存储属性是指第一次使用到该变量再进行运算(这里的运算不能依赖其他成员属性,@匿了不怕评论提示,延迟存储属性可以使用成员属性,只是需要在闭包中明确指出其持有对象本身,即加上self;也可以直接使用静态/类属性)。

延迟存储属性必须声明为var变量,因为其属性值在对象实例化前可能无法得到,而常量必须在初始化完成前拥有初始值。

在 Swift 中,可以将消耗性能才能得到的值作为延迟存储属性,即懒加载。

全局的常量和变量也是延迟存储属性,但不需要显式声明为 lazy(不支持 Playground)。

Demo

这里假定在 ViewController.swift 有一个属性,需要从 plist 文件读取内容,将其中的字典转为模型。如果 plist 文件中内容很多,那么就十分消耗性能。如果用户不触发相应事件,也没有必要加载这些数据。那么这里就很适合使用懒加载,即延迟存储属性。

classViewController:UIViewController{lazyvargoods:NSArray? = {vargoodsArray:NSMutableArray= []ifletpath =Bundle.main.path(forResource:"Goods", ofType:"plist") {ifletarray =NSArray(contentsOfFile: path) {forgoodsDictinarray { goodsArray.add(Goods(goodsDictas!NSDictionary)) }returngoodsArray } }returnnil}()// 这样也是允许的,可以把初始化的代码直接放在构造方法中lazyvartestLazy =Person()}classPerson{}

可以在延迟存储属性运算的代码中加入打印语句,即可验证其何时初始化。

Lazy 初始化的「演变」过程

根据上面 Demo,延迟存储属性的初始化代码部分可能有些让人迷惑,但其实也是初始化的一步步的演变过程。在 @Onetaway 的 【菜鸡Playground 1】Swift 中 lazy initialization 中也有描述这个过程,简单用代码表示也如下所示:

structPerson{varname =""init() {print(#function) }}// 直接初始化letp1 =Person()

// 利用闭包letgetOnePerson = { () ->Personinletp =Person()returnp}letp2 = getOnePerson()// 闭包执行letp3 = { () ->Personinletp =Person()returnp}()// 简化letp4:Person= {letp =Person()returnp}()

上一篇 下一篇

猜你喜欢

热点阅读