属性
This commit is contained in:
@@ -6,8 +6,8 @@ struct Circle {
|
||||
var radius: Double
|
||||
// 计算属性
|
||||
var diameter: Double {
|
||||
set {
|
||||
radius = newValue / 2
|
||||
set(newDiameter) {
|
||||
radius = newDiameter / 2
|
||||
}
|
||||
get {
|
||||
radius * 2
|
||||
@@ -18,3 +18,85 @@ struct Circle {
|
||||
var circle = Circle(radius: 5)
|
||||
print(circle.radius)
|
||||
print(circle.diameter)
|
||||
|
||||
struct Point {
|
||||
var x: Int
|
||||
var y: Int
|
||||
// 初始化器设置初始值
|
||||
init() {
|
||||
x = 10
|
||||
y = 20
|
||||
}
|
||||
}
|
||||
|
||||
var p = Point()
|
||||
|
||||
|
||||
struct Point3D {
|
||||
var x: Int
|
||||
var y: Int
|
||||
var z: Int
|
||||
}
|
||||
|
||||
var p3d = Point3D(x: 10, y: 20, z: 30)
|
||||
|
||||
struct PointA {
|
||||
var x: Int = 10
|
||||
var y: Int = 20
|
||||
}
|
||||
|
||||
var pa = PointA()
|
||||
|
||||
class Car {
|
||||
init() {
|
||||
print("Car init!")
|
||||
}
|
||||
|
||||
func run() {
|
||||
print("Car is running!")
|
||||
}
|
||||
}
|
||||
|
||||
class Person {
|
||||
lazy var car = Car()
|
||||
init() {
|
||||
print("Person init!")
|
||||
}
|
||||
|
||||
func goOut() {
|
||||
car.run()
|
||||
}
|
||||
}
|
||||
|
||||
let ps = Person()
|
||||
print("-----------")
|
||||
ps.goOut()
|
||||
|
||||
struct PointB {
|
||||
var x = 0
|
||||
var y = 0
|
||||
lazy var z = 0
|
||||
}
|
||||
let pb = PointB()
|
||||
//print(pb.z)
|
||||
|
||||
|
||||
|
||||
struct CircleA {
|
||||
var radius: Double {
|
||||
willSet {
|
||||
print("willSet", newValue)
|
||||
}
|
||||
didSet {
|
||||
print("didSet", oldValue, radius)
|
||||
}
|
||||
}
|
||||
init() {
|
||||
self.radius = 10
|
||||
print("Circle init!")
|
||||
}
|
||||
}
|
||||
|
||||
var circleA = CircleA()
|
||||
circleA.radius = 10.5
|
||||
print(circleA.radius)
|
||||
|
@@ -30,3 +30,181 @@ struct Circle {
|
||||
3. 结构体、类可以定义存储属性
|
||||
4. 枚举 `不可以` 定义存储属性
|
||||
|
||||
Swift 中存储属性的规定
|
||||
|
||||
* 在创建结构体或类的实例时,必须为所有的存储属性设置一个合适的初始值。
|
||||
|
||||
* 可以在初始化器里为存储属性设置一个初始值
|
||||
* 可以分配一个默认的属性值作为属性定义的一部分
|
||||
|
||||
```swift
|
||||
struct Point {
|
||||
var x: Int
|
||||
var y: Int
|
||||
// 初始化器设置初始值
|
||||
init() {
|
||||
x = 10
|
||||
y = 20
|
||||
}
|
||||
}
|
||||
|
||||
var p = Point()
|
||||
|
||||
struct Point3D {
|
||||
var x: Int
|
||||
var y: Int
|
||||
var z: Int
|
||||
}
|
||||
// 初始化器设置初始值
|
||||
var p3d = Point3D(x: 10, y: 20, z: 30)
|
||||
|
||||
// 分配一个默认的属性值
|
||||
struct PointA {
|
||||
var x: Int = 10
|
||||
var y: Int = 20
|
||||
}
|
||||
|
||||
var p = PointA()
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 计算属性(Computed Property)
|
||||
|
||||
1. 本质是方法(函数)
|
||||
2. 不占实例的内存
|
||||
3. 结构体、枚举、类都可以定义计算属性
|
||||
|
||||
Swift 中计算属性的规定
|
||||
|
||||
* set 传入的新默认值叫做 `newValue` , 也可以自定义。
|
||||
|
||||
```swift
|
||||
struct Circle {
|
||||
// 存储属性
|
||||
var radius: Double
|
||||
// 计算属性
|
||||
var diameter: Double {
|
||||
set(newDiameter) {
|
||||
radius = newDiameter / 2
|
||||
}
|
||||
get {
|
||||
radius * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* 只读属性:只有 `get`,没有 `set`
|
||||
|
||||
```swift
|
||||
struct Circle {
|
||||
// 存储属性
|
||||
var radius: Double
|
||||
// 计算属性
|
||||
var diameter: Double {
|
||||
get {
|
||||
radius * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* 定义计算属性只能用 `var`, 不能用 `let`
|
||||
|
||||
##### 枚举 rawValue 的原理
|
||||
|
||||
枚举原始值 `rawValue` 的本质是: 只读计算属性
|
||||
|
||||
#### 延迟存储属性 (Lazy Stored Property)
|
||||
|
||||
使用 `lazy` 可以定义一个延迟存储属性,在第一次用到属性的时候才会进行初始化。
|
||||
|
||||
* `lazy` 属性必须是 `var` , 不能是 `let`
|
||||
* `let` 必须在示例的初始化方法完成之前就拥有值
|
||||
* 如果多条线程同时第一次访问 `lazy` 属性
|
||||
* 无法保证属性只能被初始化 1 次的,是线程不安全的
|
||||
|
||||
```swift
|
||||
class Car {
|
||||
init() {
|
||||
print("Car init!")
|
||||
}
|
||||
|
||||
func run() {
|
||||
print("Car is running!")
|
||||
}
|
||||
}
|
||||
|
||||
class Person {
|
||||
lazy var car = Car()
|
||||
init() {
|
||||
print("Person init!")
|
||||
}
|
||||
|
||||
func goOut() {
|
||||
car.run()
|
||||
}
|
||||
}
|
||||
|
||||
let ps = Person()
|
||||
print("-----------")
|
||||
ps.goOut()
|
||||
```
|
||||
|
||||
输出的结果
|
||||
|
||||
> Person init!
|
||||
>
|
||||
> \------------
|
||||
>
|
||||
> Car init!
|
||||
> Car is running!
|
||||
|
||||
##### 延迟存储属性注意点
|
||||
|
||||
当结构体包含一个延迟存储属性时,只有 `var` 才能访问延迟存储属性
|
||||
|
||||
* 因为延迟属性初始化时需要改变结构体内存
|
||||
|
||||
<img src="/Users/jiulinxiri/Library/Application%20Support/CleanShot/media/media_iEAVQA9pST/jiulinxiri_20220109234238.png" alt="jiulinxiri_20220109234238" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
#### 属性观察器(Property Observer)
|
||||
|
||||
属性观察器类似于 OC 的 KVO,可以为非 `lazy` 的 `var` 存储属性设置观察器。
|
||||
|
||||
```swift
|
||||
struct CircleA {
|
||||
var radius: Double {
|
||||
willSet {
|
||||
print("willSet", newValue)
|
||||
}
|
||||
didSet {
|
||||
print("didSet", oldValue, radius)
|
||||
}
|
||||
}
|
||||
init() {
|
||||
self.radius = 10
|
||||
print("Circle init!")
|
||||
}
|
||||
}
|
||||
|
||||
// Circle init!
|
||||
var circleA = CircleA()
|
||||
// willSet 10.5
|
||||
// didSet 10.0 10.5
|
||||
circleA.radius = 10.5
|
||||
// 10.5
|
||||
print(circleA.radius)
|
||||
```
|
||||
|
||||
> willSet、didSet 以及 set 方法是不能共存的,因此计算属性不能设置属性观察器
|
||||
|
||||
* `willSet` 会传递新值,默认叫 newValue
|
||||
* `didSet` 会传递旧值,默认叫 oldValue
|
||||
* 在初始化器中设置属性值不会触发 `willSet` 和 `didSet`
|
||||
* 在属性定义时设置初始值不会触发 `willSet` 和 `didSet`
|
||||
|
||||
#### 全局变量/局部变量
|
Binary file not shown.
Reference in New Issue
Block a user