SwiftUI 2.0 课程笔记 Chapter 3

https://www.bilibili.com/video/BV1q64y1d7x5?p=3

文章目录

      • MVVM架构
      • Swift的类型系统
        • struct与class
        • 泛型Generics
        • 函数Function
      • MVVM实例
        • Model
        • ViewModel

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
      }
      init(anotherNumber: Int){
        // 可以有多个init
      }
    }
    

不同点

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

//Model
struct MemoryGame<CardContend>{
    //private(set) 代表只读
    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))
        }
    }
  
    //MemoryGame.Card
    struct Card{
        var isFaceUp: Bool = false
        var isMatched: Bool = false
        var content : CardContend
    }
}

ViewModel

//ViewModel
class EmojiMemoryGame{
    //static类型的初始化顺序在普通var之前
    //因此static类型的类成员可以作为其他类成员的默认值使用
    //如 var a = EmojiMemoryGame.emojis[1]
    static var emojis = ["","","","","","","","","","",
                  "","","","","","","","","","",""]
    
    static func createMemoryGame() -> MemoryGame<String> {
        return MemoryGame<String>(numberOfPairsOfCards: 2, createCardContent: {
            // 定义中:createCardContent: (Int) -> CardContend //CardContend是一个泛型
            // 因此,此处会自动识别类型,将
            // index in 识别为 (index: Int) -> String in
            index in
            return EmojiMemoryGame.emojis[index]
        } )
    }
    
    private var model: MemoryGame<String> = EmojiMemoryGame.createMemoryGame()

    
    var cards: Array<MemoryGame<String>.Card>{
        //只读
        return model.cards
    }
}

你可能感兴趣的:(iOS,Swift,swift,swiftui,ui)