如何在观察者模式中创建一个 class 实例?
How to create a class instance in Observer pattern?
我在下面的代码中实现了一个观察者模式。但是,我不确定如何创建 SeasonSubject class 的实例以调用 addObserver() 函数?
我不想在我的视图控制器中创建它。请参考以下代码。
//
// SeasonViewController.swift
// PhotoCalender
//
// Created by Suraj M Gaikwad on 09/07/21.
//
import UIKit
enum Season: String {
case summer
case winter
case monsoon
case none
}
protocol SeasonObserver {
func onSeasonChange(_season: Season)
}
class PhotoframeObserver: SeasonObserver {
var delegate: SeasonViewControllerDelegate?
init(_delegate: SeasonViewControllerDelegate) {
delegate = _delegate
}
func onSeasonChange(_season: Season) {
switch _season {
case .monsoon, .summer, .winter:
delegate?.changeTheLayoutPer(_season: _season)
case .none:
debugPrint("none")
}
}
}
class PhotoDetailsObserver: SeasonObserver {
var delegate: SeasonViewControllerDelegate?
init(_delegate: SeasonViewControllerDelegate) {
delegate = _delegate
}
func onSeasonChange(_season: Season) {
switch _season {
case .monsoon, .summer, .winter:
delegate?.changeTheTitle(_season: _season)
case .none:
debugPrint("none")
}
}
}
protocol SeasonSubjectProtocol {
func informTheSeasonChange(_season: Season)
}
class SeasonSubject: SeasonSubjectProtocol {
private var _season = Season.none
var changedSeason: Season {
get {
_season
}
set {
_season = newValue
}
}
private var seasonObserver = [SeasonObserver]()
func addObserver(_observer: SeasonObserver) {
seasonObserver.append(_observer)
}
func removeObserver(_observer: SeasonObserver) {
// seasonObserver.remove(at: 0)
}
private func notifyObserver() {
seasonObserver.forEach { [=11=].onSeasonChange(_season: _season)
}
}
func informTheSeasonChange(_season: Season) {
changedSeason = _season
}
deinit {
seasonObserver.removeAll()
}
}
protocol SeasonViewControllerDelegate {
func changeTheLayoutPer(_season: Season)
func changeTheTitle(_season: Season)
}
class SeasonViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var backgroundView: UIView!
@IBOutlet weak var seasonTitle: UILabel!
var delegate: SeasonSubjectProtocol?
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .white
self.seasonTitle.text = "none"
}
@IBAction func changeTheSeason(_ sender: UIButton) {
if count > 2 {
count = 0
return
}
if count == 0 {
delegate?.informTheSeasonChange(_season: Season.summer)
}
if count == 1 {
delegate?.informTheSeasonChange(_season: Season.winter)
}
if count == 2 {
delegate?.informTheSeasonChange(_season: Season.monsoon)
}
count += 1
}
}
extension SeasonViewController: SeasonViewControllerDelegate {
func changeTheLayoutPer(_season: Season) {
switch _season {
case .monsoon:
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .gray
case .summer:
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .orange
case .winter:
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .blue
case .none:
debugPrint("none")
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .white
}
}
func changeTheTitle(_season: Season) {
switch _season {
case .monsoon, .summer, .winter, .none:
self.seasonTitle.text = _season.rawValue
}
}
}
我想创建一个 SeasonSubject() 实例 class。我想调用 addObserver 和 removeObserver() 方法。
您可以创建 SeasonSubject
作为单例实例,它已经维护了一个观察者数组,因此多个观察者可以在整个应用程序中使用同一个实例。
class SeasonSubject: SeasonSubjectProtocol {
static let shared = SeasonSubject()
}
你现在需要做的就是 - 从你想要的地方调用这个单例实例的 addObserver
/ removeObserver
。
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
SeasonSubject.shared.addObserver(self)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
SeasonSubject.shared.removeObserver(self)
}
}
注意:您必须确保这些 add/remove 调用是平衡的,否则您将落入观察者永远不会被释放的陷阱。
如果你想远离这个问题 - 你应该考虑一个基于 NotificationCenter
的实现,你的观察者永远不会有永远保留在内存中的风险。
我在下面的代码中实现了一个观察者模式。但是,我不确定如何创建 SeasonSubject class 的实例以调用 addObserver() 函数? 我不想在我的视图控制器中创建它。请参考以下代码。
//
// SeasonViewController.swift
// PhotoCalender
//
// Created by Suraj M Gaikwad on 09/07/21.
//
import UIKit
enum Season: String {
case summer
case winter
case monsoon
case none
}
protocol SeasonObserver {
func onSeasonChange(_season: Season)
}
class PhotoframeObserver: SeasonObserver {
var delegate: SeasonViewControllerDelegate?
init(_delegate: SeasonViewControllerDelegate) {
delegate = _delegate
}
func onSeasonChange(_season: Season) {
switch _season {
case .monsoon, .summer, .winter:
delegate?.changeTheLayoutPer(_season: _season)
case .none:
debugPrint("none")
}
}
}
class PhotoDetailsObserver: SeasonObserver {
var delegate: SeasonViewControllerDelegate?
init(_delegate: SeasonViewControllerDelegate) {
delegate = _delegate
}
func onSeasonChange(_season: Season) {
switch _season {
case .monsoon, .summer, .winter:
delegate?.changeTheTitle(_season: _season)
case .none:
debugPrint("none")
}
}
}
protocol SeasonSubjectProtocol {
func informTheSeasonChange(_season: Season)
}
class SeasonSubject: SeasonSubjectProtocol {
private var _season = Season.none
var changedSeason: Season {
get {
_season
}
set {
_season = newValue
}
}
private var seasonObserver = [SeasonObserver]()
func addObserver(_observer: SeasonObserver) {
seasonObserver.append(_observer)
}
func removeObserver(_observer: SeasonObserver) {
// seasonObserver.remove(at: 0)
}
private func notifyObserver() {
seasonObserver.forEach { [=11=].onSeasonChange(_season: _season)
}
}
func informTheSeasonChange(_season: Season) {
changedSeason = _season
}
deinit {
seasonObserver.removeAll()
}
}
protocol SeasonViewControllerDelegate {
func changeTheLayoutPer(_season: Season)
func changeTheTitle(_season: Season)
}
class SeasonViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var backgroundView: UIView!
@IBOutlet weak var seasonTitle: UILabel!
var delegate: SeasonSubjectProtocol?
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .white
self.seasonTitle.text = "none"
}
@IBAction func changeTheSeason(_ sender: UIButton) {
if count > 2 {
count = 0
return
}
if count == 0 {
delegate?.informTheSeasonChange(_season: Season.summer)
}
if count == 1 {
delegate?.informTheSeasonChange(_season: Season.winter)
}
if count == 2 {
delegate?.informTheSeasonChange(_season: Season.monsoon)
}
count += 1
}
}
extension SeasonViewController: SeasonViewControllerDelegate {
func changeTheLayoutPer(_season: Season) {
switch _season {
case .monsoon:
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .gray
case .summer:
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .orange
case .winter:
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .blue
case .none:
debugPrint("none")
self.imageView.image = UIImage()
self.backgroundView.backgroundColor = .white
}
}
func changeTheTitle(_season: Season) {
switch _season {
case .monsoon, .summer, .winter, .none:
self.seasonTitle.text = _season.rawValue
}
}
}
我想创建一个 SeasonSubject() 实例 class。我想调用 addObserver 和 removeObserver() 方法。
您可以创建 SeasonSubject
作为单例实例,它已经维护了一个观察者数组,因此多个观察者可以在整个应用程序中使用同一个实例。
class SeasonSubject: SeasonSubjectProtocol {
static let shared = SeasonSubject()
}
你现在需要做的就是 - 从你想要的地方调用这个单例实例的 addObserver
/ removeObserver
。
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
SeasonSubject.shared.addObserver(self)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
SeasonSubject.shared.removeObserver(self)
}
}
注意:您必须确保这些 add/remove 调用是平衡的,否则您将落入观察者永远不会被释放的陷阱。
如果你想远离这个问题 - 你应该考虑一个基于 NotificationCenter
的实现,你的观察者永远不会有永远保留在内存中的风险。