diff --git a/10 属性 inout.playground/Contents.swift b/10 属性 inout.playground/Contents.swift index a7afccc..82c3e85 100644 --- a/10 属性 inout.playground/Contents.swift +++ b/10 属性 inout.playground/Contents.swift @@ -1,4 +1,5 @@ import UIKit +import CoreGraphics struct Circle { @@ -100,3 +101,70 @@ struct CircleA { var circleA = CircleA() circleA.radius = 10.5 print(circleA.radius) + +struct Shape { + var width: Int + var side: Int { + willSet { + print("willSetSide", newValue) + } + didSet { + print("didSetSide", oldValue, side) + } + } + var girth: Int { + set { + width = newValue / side + print("setGirth", newValue) + } + get { + print("getGirth") + return width * side + } + } + func show() { + print("width=\(width), side=\(side), girth=\(girth)") + } +} + +func test(_ num: inout Int) { + num = 20 +} +var s = Shape(width: 10, side: 4) +test(&s.width) +s.show() +print("----------") +test(&s.side) +s.show() +print("----------") +test(&s.girth) +s.show() + +struct CarA { + static var count: Int = 0 + init() { + CarA.count += 1 + } +} + +let c1 = CarA() +let c2 = CarA() +let c3 = CarA() + +print(CarA.count) + + +// 单例模式 +public class FileManager { + // 延迟初始化 + public static let shared = FileManager() + // 禁止外部初始化 + private init() {} + // 方法 + func run() { + + } +} + +FileManager.shared.run() + diff --git a/10 属性 inout.playground/Resources/README.md b/10 属性 inout.playground/Resources/README.md index 6f660b4..8c74c14 100644 --- a/10 属性 inout.playground/Resources/README.md +++ b/10 属性 inout.playground/Resources/README.md @@ -215,4 +215,123 @@ print(circleA.radius) * 在初始化器中设置属性值不会触发 `willSet` 和 `didSet` * 在属性定义时设置初始值不会触发 `willSet` 和 `didSet` -#### 全局变量/局部变量 \ No newline at end of file +#### 全局变量/局部变量 + +属性观察器、计算属性的功能,也可以应用在全局变量以及局部变量。 + + + +#### inout + +inout的本质就是引用传递(地址传递) + +* 如果实参有物理内存地址,且没有设置属性观察器 + * 直接将实参的内存地址传入函数(实参进行引用传递) +* 如果实参是计算属性或者设置了属性观察器 + * 采取了CopyInCopyOut的做法 + * 调用该函数时,先复制实参的值,产生副本【get】 + * 将副本的内存地址传入函数(副本进行引用传递),在函数内部可以修改副本的值 + * 函数返回后,再将副本的值覆盖实参的值【set】 + +```swift +struct Shape { + // 没有设置属性观察器 + var width: Int + // 设置属性观察器 + var side: Int { + willSet { + print("willSetSide", newValue) + } + didSet { + print("didSetSide", oldValue, side) + } + } + var girth: Int { + set { + width = newValue / side + print("setGirth", newValue) + } + get { + print("getGirth") + return width * side + } + } + func show() { + print("width=\(width), side=\(side), girth=\(girth)") + } +} + +func test(_ num: inout Int) { + num = 20 +} +var s = Shape(width: 10, side: 4) +test(&s.width) +s.show() +print("----------") +test(&s.side) +s.show() +print("----------") +test(&s.girth) +s.show() +``` + +输出的结果 + +jiulinxiri_20220110114314 + + + +#### 类型属性(Type Property) + +类型属性主要是通过 `static` 定义类型属性,枚举类型也可以定义类型属性(存储类型属性、计算类型属性) + +属性分类 + +* 实例属性(Instance Property): 只能通过实例去访问 + * 存储实例属性 (Stored Instance Property): 存储在实例的内存中,每个实例都有 1 份 + * 计算实例属性 (Computed Instance Property) +* 类型属性(Type Property): 只能通过类型去访问 + * 存储类型属性(Stored Type Property): 整个程序运行的过程中,就只有 1 份内存(类似于全局变量) + * 存储类型属性默认就是 `lazy`,会在第一次使用的时候才初始化 + * 就算被多个线程同时访问,保证只会初始化一次 + * 存储类型属性可以是 `let` + * 计算类型属性(Computed Type Property) + +```swift +struct CarA { + // 存储类属性 + static var count: Int = 0 + init() { + CarA.count += 1 + } +} + +let c1 = CarA() +let c2 = CarA() +let c3 = CarA() + +print(CarA.count) +``` + + + +#### 单例模式 + +```swift +// 单例模式 +public class FileManager { + // 延迟初始化 + public static let shared = FileManager() + // 禁止外部初始化 + private init() {} + // 方法 + func run() { + + } +} + +FileManager.shared.run() +``` + + + diff --git a/10 属性 inout.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate b/10 属性 inout.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate index 7e65190..9b34159 100644 Binary files a/10 属性 inout.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate and b/10 属性 inout.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/10 属性 inout.playground/xcuserdata/jiulinxiri.xcuserdatad/xcschemes/xcschememanagement.plist b/10 属性 inout.playground/xcuserdata/jiulinxiri.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..686b0aa --- /dev/null +++ b/10 属性 inout.playground/xcuserdata/jiulinxiri.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,16 @@ + + + + + SchemeUserState + + 10 属性 inout (Playground).xcscheme + + isShown + + orderHint + 0 + + + + diff --git a/11 方法.playground/Contents.swift b/11 方法.playground/Contents.swift new file mode 100644 index 0000000..c7c4a9d --- /dev/null +++ b/11 方法.playground/Contents.swift @@ -0,0 +1,41 @@ +import Cocoa + + +class Car { + static var cout = 0 + init() { + Car.cout += 1 + } + + static func getCount() -> Int {cout} +} + +let c0 = Car() +let c1 = Car() +let c2 = Car() +// 3 +print(Car.getCount()) + + +struct Point { + var x = 0.0, y = 0.0 + mutating func moveBy(deltaX: Double, deltaY: Double) { + x += deltaX + y += deltaY + // self = Point(x: x + deltaX, y: y + deltaY) + } +} + +enum StateSwitch { + case low, middle, high + mutating func next() { + switch self { + case .low: + self = .middle + case .middle: + self = .high + case .high: + self = .low + } + } +} diff --git a/11 方法.playground/Resources/README.md b/11 方法.playground/Resources/README.md new file mode 100644 index 0000000..e734782 --- /dev/null +++ b/11 方法.playground/Resources/README.md @@ -0,0 +1,79 @@ +### 方法 + +枚举、结构体、类都可以定义实例方法、类方法 + +* 实例方法(Instance Method) + * 通过实例调用 +* 类方法(Type Method) + * 通过类型调用,用 `static` 或者 `class` 关键字定义 + +```swift +class Car { + static var cout = 0 + init() { + Car.cout += 1 + } + + static func getCount() -> Int { + // 等价于 self.cout、Car.cout + cout + } +} + +let c0 = Car() +let c1 = Car() +let c2 = Car() +// 3 +print(Car.getCount()) +``` + +#### self + +* 在实例方法中代表实例 +* 在类型方法中代表类型 + +#### mutating + +结构体和枚举是**值类型**,默认情况下,值类型的属性不能被自身的实例方法修改。在 `func` 关键字前加 `mutating` 可以允许这种修改行为。 + +```swift +struct Point { + var x = 0.0, y = 0.0 + mutating func moveBy(deltaX: Double, deltaY: Double) { + x += deltaX + y += deltaY + // self = Point(x: x + deltaX, y: y + deltaY) + } +} + +enum StateSwitch { + case low, middle, high + mutating func next() { + switch self { + case .low: + self = .middle + case .middle: + self = .high + case .high: + self = .low + } + } +} +``` + +#### @discardableResult + +在 `func` 前面加个 `@discardableResult` ,可以消除:函数调用后返回值未被使用的警告⚠ + +```swift +struct Point { + var x = 0.0, y = 0.0 + @discardableResult mutating + func moveX(deltaX: Double) -> Double { + x += deltaX + return x + } +} +var p = Point() +p.moveX(deltaX: 10) +``` \ No newline at end of file diff --git a/11 方法.playground/contents.xcplayground b/11 方法.playground/contents.xcplayground new file mode 100644 index 0000000..1c968e7 --- /dev/null +++ b/11 方法.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/11 方法.playground/playground.xcworkspace/contents.xcworkspacedata b/11 方法.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ca3329e --- /dev/null +++ b/11 方法.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/11 方法.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate b/11 方法.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..ed8c864 Binary files /dev/null and b/11 方法.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/11 方法.playground/timeline.xctimeline b/11 方法.playground/timeline.xctimeline new file mode 100644 index 0000000..bf468af --- /dev/null +++ b/11 方法.playground/timeline.xctimeline @@ -0,0 +1,6 @@ + + + + + diff --git a/12 下标.playground/Contents.swift b/12 下标.playground/Contents.swift new file mode 100644 index 0000000..1f80fea --- /dev/null +++ b/12 下标.playground/Contents.swift @@ -0,0 +1,32 @@ +import Cocoa + +class Point { + var x = 0.0, y = 0.0 + subscript(index: Int) -> Double { + set { + if index == 0 { + x = newValue + } else if index == 1 { + y = newValue + } + } + + get { + if index == 0 { + return x + } else if index == 1 { + return y + } + + return 0 + } + } +} + +var p = Point() +p[0] = 11.1 +p[1] = 22.2 +print(p.x) +print(p.y) +print(p[0]) +print(p[1]) diff --git a/12 下标.playground/Resources/README.md b/12 下标.playground/Resources/README.md new file mode 100644 index 0000000..9e33f43 --- /dev/null +++ b/12 下标.playground/Resources/README.md @@ -0,0 +1,81 @@ +### 下标(subscript) + +使用 `subscript` 可以给任意类型(枚举、结构体、类)增加下标功能。`subscript` 的语法类似于实例方法、计算属性,本质就是方法(函数) + +```swift +class Point { + var x = 0.0, y = 0.0 + subscript(index: Int) -> Double { + set { + if index == 0 { + x = newValue + } else if index == 1 { + y = newValue + } + } + + get { + if index == 0 { + return x + } else if index == 1 { + return y + } + + return 0 + } + } +} + +var p = Point() +p[0] = 11.1 +p[1] = 22.2 +print(p.x) +print(p.y) +print(p[0]) +print(p[1]) +``` + +`subscript` 中定义的返回值类型决定了 + +* get方法的返回值类型 +* set方法中newValue的类型 + +`subscript` 可以接受多个参数,并且类型任意 + +#### 下标细节 + +1. `subscripte` 可以没有 `set` 方法,但是必须有 `get` 方法 + +2. 如果只有 `get` 方法,可以省略 `get` + +3. 可以设置参数标签 + + ```swift + class Point { + var x = 0.0, y = 0.0 + subscript(index i: Int) -> Double { + if i == 0 { + return x + } else if i == 1 { + return y + } + return 0 + } + } + var p = Point() + p.y = 22.2 + print(p[index: 1]) // 22.2 + ``` + +4. 下标可以是类型方法 + + ```swift + class Sum { + static subscript(v1: Int, v2: Int) -> Int { + return v1 + v2 + } + } + print(Sum[10, 20]) // 30 + ``` + + diff --git a/12 下标.playground/contents.xcplayground b/12 下标.playground/contents.xcplayground new file mode 100644 index 0000000..1c968e7 --- /dev/null +++ b/12 下标.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/12 下标.playground/playground.xcworkspace/contents.xcworkspacedata b/12 下标.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ca3329e --- /dev/null +++ b/12 下标.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/12 下标.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate b/12 下标.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..665923a Binary files /dev/null and b/12 下标.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/13 继承.playground/Contents.swift b/13 继承.playground/Contents.swift new file mode 100644 index 0000000..9d86688 --- /dev/null +++ b/13 继承.playground/Contents.swift @@ -0,0 +1,3 @@ +import UIKit + +var greeting = "Hello, playground" diff --git a/13 继承.playground/contents.xcplayground b/13 继承.playground/contents.xcplayground new file mode 100644 index 0000000..7627317 --- /dev/null +++ b/13 继承.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/13 继承.playground/playground.xcworkspace/contents.xcworkspacedata b/13 继承.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ca3329e --- /dev/null +++ b/13 继承.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/13 继承.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate b/13 继承.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..aed6638 Binary files /dev/null and b/13 继承.playground/playground.xcworkspace/xcuserdata/jiulinxiri.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/13 继承.playground/timeline.xctimeline b/13 继承.playground/timeline.xctimeline new file mode 100644 index 0000000..bf468af --- /dev/null +++ b/13 继承.playground/timeline.xctimeline @@ -0,0 +1,6 @@ + + + + + diff --git a/13 继承.playground/xcuserdata/jiulinxiri.xcuserdatad/xcschemes/xcschememanagement.plist b/13 继承.playground/xcuserdata/jiulinxiri.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..1c4c619 --- /dev/null +++ b/13 继承.playground/xcuserdata/jiulinxiri.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,16 @@ + + + + + SchemeUserState + + 13 继承 (Playground).xcscheme + + isShown + + orderHint + 0 + + + +