Swift3.0学习笔记-Properties

这篇博客介绍了Swift3.0中的属性特性,包括lazy关键字用于延迟初始化,get和set语法与Java的getter、setter对比,以及只读属性和静态变量(static和class var)的使用。还提到了Swift中的Observer功能通过willSet和didSet实现,以及如何在派生类中覆盖静态变量。

https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID254


        Swift属性即成员变量跟其它语言类似, 包含变量、常量等。 


     Swift提供了lazy关键字, 即实例化结构体时不实例化成员变量, 当第一次调用lazy属性时才真正的实例化。使用lazy属性的场景: 1、 实例化结构体时,不知道某个属性该赋什么值(Java里一般赋初值0或null); 2、该属性需要经过比较耗时的计算后得出(就是说某个属性不常用且初始化会比较耗时,在用的时候再去实例化)。

     PS:在Java里没有跟lazy功能类似的关键字, 也没发现什么问题。

class DataImporter {
    var filename = "data.txt"
}

class DataManager {
    lazy var importer = DataImporter()
    var data = [String]()
}
let manager = DataManager()  //importer变量并没有实例化
print("\(manager.importer)") //第一次调用时实例化lazy变量


      在Java里提供了getter和setter方法, Swift也实现了get和set语法。 区别是Swift的get、set方法是在声明参数时实现。

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
            origin.y = newCenter.y
        }
    }
}
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("squre.orgin is now at \(square.origin.x),\(square.origin.y)")
print("initialSquare \(initialSquareCenter.x),\(initialSquareCenter.y)")
输出

squre.orgin is now at 15.0,15.0

initialSquare 5.0,5.0


     已经多次提到Swift尽量减少代码的原则, 我们看到上面的set方法肯定会带个参数, Swift设计了一个默认参数newValue,而且可以有多个get、set方法。

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
            origin.y = newCenter.y
        }
    }
    var test: Point {
        get {
            return Point(x: 80.0, y: 90.0)
        }
        set {   //对于set方法,Swift使用newValue作为默认参数!
            origin.x = newValue.x
            origin.y = newValue.y
        }
    }
}
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("squre.orgin is now at \(square.origin.x),\(square.origin.y)")
print("initialSquare \(initialSquareCenter.x),\(initialSquareCenter.y)")
print("test value \(square.test.x),\(square.test.y)")

squre.orgin is now at 15.0,15.0

initialSquare 5.0,5.0

test value 80.0,90.0


摘自Alamofire set/get的高级用法:get和set可以设置不同的访问权限。 如下面代码, set是internal访问权限, get是open访问权限。

    open internal(set) var delegate: TaskDelegate {
        get {
            taskDelegateLock.lock() ; defer { taskDelegateLock.unlock() }
            return taskDelegate
        }
        set {
            taskDelegateLock.lock() ; defer { taskDelegateLock.unlock() }
            taskDelegate = newValue
        }
    }


只读属性,即只有get方法, 没有set方法。 只读属性跟let关键字都是设置常量, 区别是let必须使用常量赋值, 而get方法可以使用变量赋值。通过修改变量仍然可以改变get方法的返回值!

struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {    //只读属性简写
        return width * height * depth
    }
    var volume1: Double {  //只读属性
        get {
            return width * height * depth
        }
    }
}

属性变化监听器Observer, 感觉很像Android的TextWatcher, 修改前执行willSet,修改后执行didSet. 使用场景:didSet跟Observer的功能是一样的,willSet是Swift新加的特性, 可以做一些准备工作。

struct Cuboid {

    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {    //只读属性
        return width * height * depth
    }
    var volume1: Double {  //只读属性简写
        get {
            return width * height * depth
        }
    }
    var volume2: Double = 0.0 {
        willSet(newVolume) {   //每次修改值前会执行
            print("volume2:\(volume2), newVolume:\(newVolume)")
        }
        didSet {  //修改值后被执行
            print("volume2:\(volume2)")
        }
    }
}

var cuboid = Cuboid()
cuboid.volume2 = 11.0

volume2:0.0, newVolume:11.0

volume2:11.0



静态变量static, 跟c/Java语言一样, 使用类名访问并强制要求有初值或get、set方法。 结构体、类都可以声明静态变量。相比于C/Java, SWift新增class var关键字用法, 也是声明静态变量, 能够在派生类里覆盖。

class SomeClass {
    static var storedTypeProperty = "Some Value." //静态可读写属性
    static var computedTypeProperty: Int { //静态只读属性,派生类不能覆盖
        return 27
    }
    
    static var modifyvalue = 0
    class var overrideableProperty: Int {  //派生类可以覆盖
        return 107
    }
}

SomeClass.modifyvalue = 5
print("overrideableProperty:\(SomeClass.overrideableProperty)")

class SomeClassExt: SomeClass {
    override class var overrideableProperty: Int {  //覆盖基类属性
       return 208
    }
    //override static var modifyvalue = 1 //Cannot override with a stored property 'modifyvalue'
}
print("overrideablePropertyExt:\(SomeClassExt.overrideableProperty)")

overrideableProperty:107

overrideablePropertyExt:208

   对于Swift的静态属性, 要记住class var的用法, 能够使用派生类覆盖基类的静态只读属性。



Swift的属性语法包括:

1、get/set方法, 以及设置常量表达式(不是常量哦!这是跟let关键字的区别);

2、willSet/didSet语法实现Observer功能;

3、static静态变量, 以及class var声明静态可覆盖变量;

 

   

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值