swift基础笔记5-属性

前端之家收集整理的这篇文章主要介绍了swift基础笔记5-属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

摘要属性将值跟特定的类、结构或枚举关联。存储属性存储常量或变量作为实例的一部分,而计算属性计算(不是存储)一个值。计算属性可以用于类、结构体和枚举,存储属性只能用于类和结构体。
存储属性和计算属性通常与特定类型的实例关联。但是,属性也可以直接作用于类型本身,这种属性称为类型属性
另外,还可以定义属性观察器来监控属性值的变化,以此来触发一个自定义的操作。属性观察器可以添加到自己定义的存储属性上,也可以添加到从父类继承的属性上。

存储属性

一个存储属性就是存储在特定类或结构体的实例里的一个常量或变量。可以使变量也可以是常量var/let。
可以在定义存储属性时制定默认值,也可以在构造过程中设置修改存储属性的值,甚至修改常量存储属性的值(参考默认属性值,在初始化阶段修改常量存储属性)。

常量结构体的存储属性

如果创建了一个结构体的实例并将其赋值给一个常量,则无法修改该实例的任何属性,即使定义了变量存储属性。这种行为是由于结构体(struct)属于值类型。
当值类型的实例被声明为常量的时候,它的所有属性也就成了常 量。
属于引用类型的类(class)则不一样。把一个引用类型的实例赋给一个常量后,仍然可以修改该实例的变量属 性。

延迟存储属性

延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。在属性声明前使用 lazy 来标示一个延迟存储 属性
注意:必须将延迟存储属性声明成变量(使用 var 关键字),因为属性的初始值可能在实例构造完成之后才会得 到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性
由于使用了 lazy,延迟存储属性只有在第一次被访问的时候才被创建。如果一个被标记为 lazy 的属性在没有初始化时就同时被多个线程访问,则无法保证该属性只会被初始化一次。

存储属性和实例变量

。。。

计算属性

//计算属性
        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.0
                    let centerY = origin.y+size.height/2.0
                    return Point(x: centerX,y: centerY)
                }
                //setter声明
                set(newCenter){
                    origin.x = newCenter.x-size.width/2.0
                    origin.y = newCenter.y-size.height/2.0
                }
            }
        }

        var square = Rect(origin: Point(x: 0.0,y: 0.0),size: Size(width:10.0,height:10.0))
        let initialSquareCenter = square.center
        print("initialAquareCenter \(initialSquareCenter)")

        square.center = Point(x: 15.0,y: 15.0)
        print("initialAquareCenter \(initialSquareCenter)")
        print("square.origin is now at(\(square.origin.x),\(square.origin.y))")

便捷setter声明

如果计算属性的 setter 没有定义表示新值的参数名,则可以使用默认名称 newValue 。下面是使用了便捷 sette r 声明的 Rect 结构体代码:

struct AlternativeRect { 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 {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2) }
}
 }

只读计算属性

只有 getter 没有 setter 的计算属性就是只读计算属性。只读计算属性总是返回一个值,可以通过点运算符访 问,但不能设置新的值。
只读计算属性的声明可以去掉 get 关键字和花括号:

//根据长宽高计算体积
struct Cuboid {
var width = 0.0,height = 0.0,depth = 0.0 var volume: Double {
return width * height * depth }
}
let fourByFiveByTwo = Cuboid(width: 4.0,height: 5.0,depth: 2.0) print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)") // 输出 "the volume of fourByFiveByTwo is 40.0"

属性观察器

属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外。
可以为除了延迟存储属性之外的其他存储属性添加属性观察器,也可以通过重载属性的方式为继承的属性(包括 存储属性和计算属性)添加属性观察器。
可以为属性添加如下的一个或全部观察器:
• willSet 在新的值被设置之前调用
• didSet 在新的值被设置之后立即调用
willSet 观察器会将新的属性值作为常量参数传入,在 willSet 的实现代码中可以为这个参数指定一个名称,如果不指定则参数仍然可用,这时使用默认名称 newValue 表示。
类似地,didSet 观察器会将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名 oldValue 。
下面是一个willSet和didSet的实际例子,其中定义了一个名为SetpCounter的类,用来统计当人步行时的步数。这个类可以跟计步器或其他日常锻炼的统计装置的输入数据配合使用。

class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
} }
} }
let stepCounter = StepCounter() stepCounter.totalSteps = 200
// About to set totalSteps to 200 // Added 200 steps stepCounter.totalSteps = 360
// About to set totalSteps to 360 // Added 160 steps stepCounter.totalSteps = 896
// About to set totalSteps to 896 // Added 536 steps

以上代码通过willset和didset观察属性stepCounter步数的变化。
注意:如果在一个属性的didSet 观察器里为它赋值,这个值会替换该观察器之前设置的值。

全局变量和局部变量

全局变量是在函数方法、闭包或任何类型之外定义的变量。局部变量是在函数方法或闭包内部定义的变量。这个跟OC和C的概念差不多,就不多说了。

类型属性

实例的属性属于一个特定类型实例,每次类型实例化后都拥有自己的一套属性值,实例之间的属性相互独立。
也可以为类型本身定义属性,不管类型有多少个实例,这些属性都只有唯一一份。这种属性就是类型属性
类型属性用于定义特定类型所有实例共享的数据,比如所有实例都能用的一个常量(就像 C 语言中的静态常 量),或者所有实例都能访问的一个变量(就像 C 语言中的静态变量)。类型本身无法在初始化过程中使用构造器给类型属性赋值。

类型属性语法

类型属性是作为类型定义的一部分写在类型最外层的花括号内,因此它的作用范围也就 在类型支持的范围内。使用关键字 static 来定义类型属性

获取和设置类型属性的值

类型属性的访问也是通过点运算符来进行,但是,类型属性是通过类型本身来获取和设置,而不是通过实例。

初学笔记,仅供参考,不喜勿喷,欢迎完善交流!

猜你在找的Swift相关文章