https://www.bilibili.com/video/BV1q64y1d7x5?p=3
MVVM架构
MVVM 全称Model-View-ViewModel 是一种设计范式(design paradigm),清楚的说明了组件的组织形式以及交互形式。
MVVM 包含用户界面代码(View) 、应用程序逻辑(Model) 与ViewModel 。
Model完全独立于UI,由数据(Data) 和逻辑(Logic) 构成。
View是Model状态的一种反射(reflection) ,用以显示当前Model的状态。这意味着View几乎是无状态(stateless) 的,View中的@State 仅仅用来重绘界面,其本质依然是stateless 。
View的代码是声明性(Declared) 的,其UI直接由body var 所定义,类似于Futter、RN等UI框架。
View是响应式 (Reactive) 的,View的body var 会随着Model的变化而变化,使界面不断的重绘。
View的响应式是由ViewModel促成的
ViewModel用于Model与View的绑定,是一种Model与View之间的解释器(Interpreter) 。
ViewModel还充当Model的守门人(Gatekeeper) ,使Model能够正确的被修改。(说白了就是类变量私有化,以保护该变量)
Model的数据通过ViewModel向View传递。其中,ViewModel会不断跟踪Model的变化(notices changes)。当Model变化时,ViewModel会发送公告,让所有View都知道Model的变化,因此,ViewModel不与任何View绑定。View可以订阅ViewModel的公告,以获取公告的内容并请求body var要求重绘UI。
Model -> ViewModel -> View有关的关键词:
Model -> ViewModel : ObservableObject、@Published、objectWillChange.send()
ViewModel -> View : @ObservedObject、@Binding、.onReceive、@Environment Object、.environmentObject()
用户的意图(intent) 也可以通过View -> ViewModel -> Model 传递。其中,View将用户的意图发送给ViewModel(call intent function),然后ViewModel转换这些意图发送给Model并对Model进行修改。
这里的意图Intent,就是用户在屏幕上的操作。如点击、滑动等。
Swift的类型系统
Swift有struct、class、protocel、generic、enum与function。
本节视频课程没有讲protocel与enum,因此只总结另外四种。
struct与class
相同点:
-
都可以存储常量(let)与变量(var) -
都可以定义函数(function)
func multiply(operand: Int, by: Int) -> Int {
return operand * by
}
multiply(operand: 5, by: 6)
func multiply(_ operand: Int, by otherOperand: Int) -> Int {
return operand * otherOperand
}
multiply(5, by: 6)
-
都有初始化器(initializer) struct/class ClassOrStructName{
init(number: Int){
}
init(anotherNumber: Int){
}
}
不同点:
struct | | class | |
---|
值类型 | Value type | 引用类型 | Reference type | 写时复制 | Copy on write。复制后并没有得到真正的副本,当对数据进行修改时才会得到副本。 | 自动引用计数 | Automatically reference counted。swift会记录指向该class的指针数目,当没有指针指向该class时,会将其从堆中清除以释放内存 | 函数式编程 | Functional programming | 面向对象编程 | Object-oriented programming | 无继承 | No inheritance | 单一继承 | Inheritance(single) | 可以init | “Free” init initializes ALL vars | 必须init | “Free” init initializes NO vars | | Mutability must be explicitly stated | | Always mutable |
尽量使用struct
泛型Generics
struct Array<Element> {
···
func append(_ element: Element) { ··· }
}
var a = Array<Int>()
a.append(5)
函数Function
func square(operand: Double) -> Double {
return operand * operand
}
operantion = square
let result = operation(4)
内联函数,又称“闭包(Closures) ”
MVVM实例
代码来自视频课程中Memory游戏项目的实例。老师着重讲了Model与ViewModel部分,View部分等到下一节再补充。
Model
import Foundation
struct MemoryGame<CardContend>{
private(set) var cards: Array<Card>
func choose(_ card: Card){
}
init(numberOfPairsOfCards: Int,createCardContent: (Int) -> CardContend){
cards = Array<Card>()
for pairIndex in 0..<numberOfPairsOfCards{
let content = createCardContent(pairIndex)
cards.append(Card(content: content))
cards.append(Card(content: content))
}
}
struct Card{
var isFaceUp: Bool = false
var isMatched: Bool = false
var content : CardContend
}
}
ViewModel
class EmojiMemoryGame{
static var emojis = ["😀","😃","😄","🥹","😅","😂","🤣","🐶","🐱","🐭",
"🐹","🐰","🦊","🐵","🐢","🍎","🍋","🍉","🥩","🍳","🦴"]
static func createMemoryGame() -> MemoryGame<String> {
return MemoryGame<String>(numberOfPairsOfCards: 2, createCardContent: {
index in
return EmojiMemoryGame.emojis[index]
} )
}
private var model: MemoryGame<String> = EmojiMemoryGame.createMemoryGame()
var cards: Array<MemoryGame<String>.Card>{
return model.cards
}
}
|