Ответ
В классическом MVC (как он часто реализуется в Cocoa/Cocoa Touch) взаимодействие происходит по принципу "Controller как посредник".
Роли компонентов:
- Model: Представляет данные и бизнес-логику. Не имеет ссылок на View или Controller. Уведомляет об изменениях (через KVO, делегаты или уведомления).
- View: Пассивный слой отображения. Отображает данные, полученные от Controller, и передает пользовательские события (тапы, ввод) обратно в Controller.
- Controller (ViewController): Координатор. Получает события от View, обрабатывает их, обновляет Model и, в ответ на изменения Model, обновляет View.
Схема потока данных:
[Действие пользователя]
↓
[Controller] ←------ (обновляет) ------ [Model]
| |
(обновляет) (уведомляет об изменениях)
| |
↓ ↓
[View] [Controller] → (обновляет) → [View]
Пример на UIKit:
// Model
struct Task {
var title: String
var isCompleted: Bool
}
// View (настроена в Storyboard/XIB или кодом)
// Содержит UILabel и UIButton. Кнопка подключена к @IBAction в Controller.
// Controller
class TaskViewController: UIViewController {
@IBOutlet weak var titleLabel: UILabel!
var task: Task! // Model
override func viewDidLoad() {
super.viewDidLoad()
updateView() // Начальная настройка View на основе Model
}
@IBAction func toggleCompletion(_ sender: UIButton) {
// Обработка события от View, изменение Model
task.isCompleted.toggle()
updateView() // Обновление View на основе измененной Model
}
private func updateView() {
// Controller обновляет View данными из Model
titleLabel.text = task.title
titleLabel.textColor = task.isCompleted ? .gray : .black
}
}
Основная проблема (Massive ViewController): Controller становится "мусорным ведром" для логики отображения, сетевых запросов, валидации данных и навигации, что затрудняет тестирование и поддержку.