Mode-View-Controller Pattern


(画像ソース:Uno's hand)

MVCの全体説明


MVCモードは3種類に分けられる.
1. Model
2. Controller
3. View
MVCはクラス図で表すと
  • モデルには、アプリケーションデータが含まれています.通常は「構造体」(struct)または「クラス」(class)として定義されます.
  • ビューでは、画面に表示要素(ボタンまたはラベル)を表示できます.一般にUIKETでは副通信UIViewの対象となる
  • コントローラは、ModelViewの間にあり、両者のコミュニケーションに役立ちます.通常、UIキットはUI ViewControllerをサブ通信しています.
  • iOSではMVCモードがよく知られています.AppleがUIKEtの構造モデルを選んだからです.したがって、対応するオブジェクト構成もあります.
    コントローラにはモデルとビューのすべてのプロパティがあるため、直接アクセスできます.だから二人の疎通はとても良いです
    class ViewController: UIViewController {
    
    	var dataModel: ViewControllerModel?
    
    	@IBOutlet weak var label: UILabel!
    	...
    	override func viewDidLoad() {
    		super.viewDidLoad()
    		label.text = dataModel?.text ?? "Uno"
    	}
    	...
    }
    コードで簡単に書きましたが、このような構造で定義されているのでしょう.
    各コントローラには、メンバー変数としてのモデルとUILabelがあります.
    ライフサイクルメソッドでは、この2つを制御しています.
    よく見ると説明の部分がありますか
    モデルとビューに強い色調はありません.
    理由は「強循環参照」の問題です.このセクションについては、後で詳しく説明します.
    まず、「メモリ管理にはホットな問題があります.この問題を解決するために、私たちはよく「弱点」を使用して問題を解決します.」そこまで理解すればいい
    Anyway
    モデルは「Property Optiver」を使用してコントローラと通信します.
    ビューはコントローラとのコミュニケーションのためにInterfaceBuilderを使用します

    これはいつ使いますか。


    UImitを使用してiOSアプリケーションを実装する場合は、既に適用されています.
    簡単なPlaygroundの例を見てみましょう.
    まず、前のユニットで述べた3つのデザインパターンを思い出しますか?
    1.構造パターン
    2.動作モード
    3.作成モード
    ここで、MVCは構造モードである.
    そこで,「オブジェクトのシステムをどのように構成するか」に興味を持つ.

    Model


    まず、モデルコードを見てみましょう.
    //MARK: - Address
    public struct Address {
        public var street: String
        public var city: String
        public var state: String
        public var zipCode: String
    }
    とても簡単です.構造をAddressに設定し、street、city、state、zipcodeと宣言します.

    Views


    以下はViewsです.
    //MARK: - AddressView
    public final class AddressView: UIView {
        @IBOutlet public var streetTextField: UITextField!
        @IBOutlet public var cityTextField: UITextField!
        @IBOutlet public var stateTextField: UITextField!
        @IBOutlet public var zipCodeTextField: UITextField!
    }
    UIViewを継承するAddressViewクラスでは、メンバー変数として4つのUItextFieldが宣言されています.
    現在の例は遊園地であるが、実際のアプリケーション項目であればxibまたはstoryboardで実現することもできる.
    addressViewと4つのUItextFieldはコミュニケーションのために@IBoutletでコミュニケーションしますね

    Controllers


    コントローラコードも
    // MARK: - AddressViewController
    public final class AddressViewController: UIViewController {
      // MARK: - Properties
      public var address: Address?
      public var addressView: AddressView! {
        guard isViewLoaded else { return nil }
        return (view as! AddressView)
      }
    	... (생명주기 함수나 이 외 메소드들) ...
    }
    「AddressViewController」は、UIViewControllerを継承していますController「address」というModelもあります.
    次の行はViewで、「addressView」と呼ばれています.
    そして、演算プログラム(Computed Property)で特定の条件で自分の戻りを宣言します.
    ビューとモデルが互いにコミュニケーションできない場合です.
    この二人はどうやってコミュニケーションしますか?
    UI ViewControllerは、ライフサイクル関数によって実現できます.
    △もちろんいろいろな方法があります.
    AddressViewController内部のviewDidLoad()updateViewFromAddress()の方法を見てみましょう.
    // MARK: - View Lifecycle
    public override func viewDidLoad() {
      super.viewDidLoad()
      updateViewFromAddress()
    }
    
    private func updateViewFromAddress() {
      guard let addressView = addressView,
        let address = address else { return }
      addressView.streetTextField.text = address.street
      addressView.cityTextField.text = address.city
      addressView.stateTextField.text = address.state
      addressView.zipCodeTextField.text = address.zipCode
    }
    address値がある場合、viewDidLoadを呼び出すと、ビューに値が割り当てられ、UIが更新されます.
    (アドレス(モデル)のデータは、UIを更新するためにアドレスビュー(AddressView)に送信される.)
    ただし、ビューがメモリに割り当てられている場合にのみUIが更新されます.
    モデルaddress値が変化したらどうなりますか?
    メモリに割り当てられているため、UIは変更されません.
    この問題(UIとデータを同期)を解決するには、Property Optiverを使用します.
    コードを見せてください.
    public var address: Address? {
      didSet {
        updateViewFromAddress()
      }
    }
    didSetという友達がいて、コードブロックで見ることができます.
    以前に宣伝された方法がある.
    didSet=「~を設定して実行{...}」そう受け入れればいい
    だからaddressで設定したのはデータを入力したという意味です
    したがって、addressにデータを入力すると、didSetのコードブロックが実行される.
    .
    これで、ビューとモデルがコントローラから接続されます.
    何を通りますか.
    ->プロのオブザーバーを直接通過~!
    でもよく考えると今は一方的모델에서 값이 변경 -> (컨트롤러) -> 뷰의 UI를 변경では、逆方向に進めばどうなるのでしょうか.뷰에서 값 사용자에가 값을 받아옴 -> (컨트롤러) -> 모델의 값을 변경以上の手順であれば.
    つまり、UImitでは@IBActionを使用して変更することができます.
    swiftuiの場合、@Stateと宣言された変数をviewに接続して直接コミュニケーションできます.(この部分はMVCモードの説明とは関係なく、後述するMVVMで説明する.)
    @IBACTION法をupdateViewFromAddress()法で実施する.
    // MARK: - Actions
    @IBAction public func updateAddressFromView(
      _ sender: AnyObject) {
      
      guard let street = addressView.streetTextField.text, 
        street.count > 0,
        let city = addressView.cityTextField.text, 
        city.count > 0,
        let state = addressView.stateTextField.text, 
        state.count > 0,
        let zipCode = addressView.zipCodeTextField.text, 
        zipCode.count > 0 else {
          // TO-DO: show an error message, handle the error, etc
          return
      }
      address = Address(street: street, city: city,
                        state: state, zipCode: zipCode)
    }
    上のコードを見て、
    コントローラに@IBACTIONメソッドを宣言.これは、現在のビューに関連付けられます.△そうすると、Controller-viewが接続されます.
    メソッド内では、address(モデル)の値を指定しながら、モデルをビューに関連付けます.
    上記の論理を完了しました.View(addressView) -> Controller(IBAction) -> Model(address)

    MVCが考慮すべき事項


    MVCモードは最初は良いスタート構造モードであった.
    しかも直感的
    コントローラにはすべてがあります.
    まるでコントローラがキッチンのプレートのようです.
    ざいりょうがある
    それをナイフ(ロジック)で国通(ビュー)に入れる.
    この手順は、コントローラファイルに表示されます.
    問題はここにある.하나의 Controllerにも見えます.
    ==コントローラにはコードとロールが多すぎます.
    この問題または困難を「メインビューコントローラ」と呼びます.
    △YouTubeや多くのブログ記事で使われている用語を目にしてください.
    iOS開発者たちはより良いモデルを探し始めました