This commit is contained in:
2022-01-10 00:02:26 +08:00
parent 5934fb2aea
commit 5686e0d1c0
3 changed files with 262 additions and 2 deletions

View File

@@ -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)

View File

@@ -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`
#### 全局变量/局部变量