MVC
关于MVC我们先来看一张图
相信很多人对这张图不陌生。那么我们一起来回顾一下MVC吧!
什么是MVC?
* Model:数据类,视图所需要的数据。
* View:视图类,构建UI界面。
* Controller: 控制类,用来控制View和Model之间的交流。
Model、View和Controller之间的关系
Controller与View
Controller
可以控制View
中显示的内容。View
中不包含任何数据,当需要数据的时候需要通过Controller
获取。
1. 目标动作机制(target-action)
可以通过`outlet`与`View`相连,例如:`storyBoard`中的`UILabel`。
2. 委托机制(delegate)
3. 数据源机制(dataSource)
Controller与Model
Controller
可以控制Model
, 他能够调用Model
中的方法
1. 广播机制(Notification)
2. KVO机制 (Key-Value Observing)
View和Model
View
和Model
之间没有直接交互,他们之间的交互全部需要通过Controller
。
CalculatorDemo
效果图
View
程序界面使用storyBoard
搭建。
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import UIKit class ViewController: UIViewController { @IBOutlet private weak var display: UILabel! private var userInTheMiddleOfTyping = false @IBAction private func targetDigit(_ sender: UIButton) { //let digit = sender.currentTitle! //容易是程序崩溃。Optional类型 if let digit = sender.currentTitle { if userInTheMiddleOfTyping { let textCurrentlyInDisplay = display.text! //textCurrentlyInDispla是String类型 display.text = textCurrentlyInDisplay + digit } else { display.text = digit } userInTheMiddleOfTyping = true } } private var displayValue: Double { get { return Double(display.text!)! } set { display.text = String(newValue) } } //调用Model private var brain = CalculatorBrain() @IBAction private func performOperation(_ sender: UIButton) { //使用Model if userInTheMiddleOfTyping { //向model传值 brain.setOperand(operand: displayValue) userInTheMiddleOfTyping = false } if let mathematicalSymbol = sender.currentTitle { //传递操作符 brain.performOperation(symbol: mathematicalSymbol) } //获取计算结果 displayValue = brain.result } }
|
Model
Model
暴露出来的接口:
1 2 3 4 5 6 7 8
| internal class CalculatorBrain {
internal func setOperand(operand: Double)
internal func performOperation(symbol: String)
internal var result: Double { get } }
|
Model 完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| class CalculatorBrain { //内部存储器,用于保存计算结果 private var accumulator = 0.0 //public 公共的方法, 接收外部传入的值 func setOperand(operand: Double) { accumulator = operand } // 一元运算符本身有相同的地方,二元运算符也是 func performOperation(symbol: String) { if let opertion = operations[symbol] { switch opertion { case .Constant(let value): accumulator = value case .UnaryOperation(let function): accumulator = function(accumulator) case .BinaryOperation(let function): executePendingBinaryOperation() pending = PendingBinaryOperationInfo(binaryFunction: function, firstOperand: accumulator) case .Equals: executePendingBinaryOperation() } } } //返回计算结果 var result: Double { get { return accumulator } } //操作符字典 private var operations: Dictionary<String, Operation> = [ "π" : Operation.Constant(M_PI), //M_PI "e" : Operation.Constant(M_E), //M_E "√" : Operation.UnaryOperation(sqrt), "cos" : Operation.UnaryOperation(cos), "*" : Operation.BinaryOperation({$0 * $1}), "+" : Operation.BinaryOperation({$0 + $1}), "-" : Operation.BinaryOperation({$0 - $1}), "÷" : Operation.BinaryOperation({$0 / $1}), "=" : Operation.Equals ] //枚举操作类型 private enum Operation { case Constant(Double) case UnaryOperation((Double) -> Double) // 关联函数类型 case BinaryOperation((Double, Double) -> Double) case Equals } //用于处理等于号 private func executePendingBinaryOperation() { if pending != nil { accumulator = pending!.binaryFunction(pending!.firstOperand, accumulator) pending = nil } } // 使用结构体存储数据 private var pending: PendingBinaryOperationInfo? private struct PendingBinaryOperationInfo { var binaryFunction: (Double, Double) -> Double var firstOperand: Double }
}
|
总结
本文是视频课程的第二课,主要讲解了MVC,内容比较基础。另外,视频大量的时间用来写讲解CalculatorDemo,大家有时间可以看视频,讲解的很清晰,相信一定会有收获。