[英]swift:Unbind listeners which are closures from array of listeners
I am trying to develop a theme engine, which loads themes from a json
. 我正在尝试开发一个主题引擎,该引擎从
json
加载主题。 I have a Thememanager
which is a singleton
class and holds a currentTheme
variable. 我有一个
Thememanager
,它是一个singleton
类,并具有currentTheme
变量。 I then have a baseViewController
which listens to any change in the currentTheme
with the help of Boxing
technique, and all the viewControllers need to be subclass of base
and need to override
the observer
method to apply their styles. 然后,我有一个
baseViewController
,它通过Boxing
技术来侦听currentTheme
任何更改,并且所有viewControllers都必须是base
子类,并且需要override
observer
方法以应用其样式。 In the box
class I have an array of listeners
so that multiple view controllers can observer theme change simultaneously, it works well and now my problem is that whenever a view controller gets deallocated
, I want to remove that listener also from the box class array of listeners, which I am unable to figure out, because of which listeners are getting piled up. 在
box
类中,我有一个listeners
器数组,以便多个视图控制器可以同时更改观察者主题,它运行良好,现在我的问题是,每当一个视图控制器被deallocated
,我也想从的box类数组中删除该侦听器。听众,我无法弄清,因为这些听众越来越多。
I tried to write an unbind
method in the deint of the viewController and tried to pass the closure like the below but it didnt work 我试图在viewController的deint中编写一个
unbind
方法,并试图像下面这样传递闭包,但是它没有用
func unbind(listener: Listener?) {
self.listeners = self.listeners.filter { $0 as AnyObject !== listener as AnyObject }
}
Thememanager 主题经理
class Thememanager {
// Hold a list of themes
var themes = [Theme]()
// Private Init
private init() {
fetchMenuItemsFromJSON()
// You can provide a default theme here.
//change(theme: defaultTheme)
}
// MARK: Shared Instance
private static let _shared = Thememanager()
// MARK: - Accessors
class func shared() -> Thememanager {
return _shared
}
var currentTheme: Box<Theme?> = Box(nil)
func change(theme: Theme) {
currentTheme.value = theme
}
private func fetchMenuItemsFromJSON() {
// TRIAL
let theme = Theme()
themes.append(theme)
}
}
BOX 框
class Box<T> {
typealias Listener = (T) -> Void
var listeners = [Listener?]()
var value: T {
didSet {
for listener in listeners{
listener?(value)
}
}
}
init(_ value: T) {
self.value = value
}
func bind(listener: Listener?) {
self.listeners.append(listener)
for listener in listeners{
listener?(value)
}
}
func unbind(listener: Listener?) {
self.listeners = self.listeners.filter { $0 as AnyObject !== listener as AnyObject }
}
}
BaseViewController BaseViewController
class BaseViewController: UIViewController {
private var themeManager = Thememanager.shared()
typealias Listener = (Theme?) -> Void
var currentListener: Listener?
override func viewDidLoad() {
super.viewDidLoad()
observeThemeChange()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Bind the theme variable so that changes are immediately effective
func observeThemeChange() {
currentListener = {[weak self] (theme) in
guard let currtheme = theme else {
return
}
self?.loadWith(theme: currtheme)
}
themeManager.currentTheme.bind(listener: currentListener)
}
// This method will be implemented by the Child classes
func loadWith(theme: Theme) {
self.navigationController?.navigationBar.tintColor = theme.navigationBarTextColor
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor : theme.navigationBarTextColor]
// Need to be implemented by child classes
print("theme changed")
}
deinit {
themeManager.currentTheme.unbind(listener: currentListener)
}
}
Theme 主题
struct Theme {
// Define all the theme properties you want to control.
var navigationBarBgColor: UIColor = UIColor.darkGray
var navigationBarTextColor: UIColor = UIColor.black
}
The issue is with the comparison of closure in unbind
method as it snot available for closures and functions(). 问题在于在
unbind
方法中比较闭包,因为它不适用于闭包和functions()。 See this . 看到这个 。 I guess you could maintain a hashmap where listeners be the value and a unique identifier be the key.
我猜您可以维护一个哈希表,其中侦听器为值,唯一标识符为键。 It is going to be much faster to unbind it as well.
解除绑定的速度也会更快。
But, I feel Notifications way is much better as it gives you the same behaviour(Publisher-Subscriber) without you having to manage the listeners. 但是,我觉得Notifications方法更好,因为它可以为您提供相同的行为(Publisher-Subscriber),而您无需管理侦听器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.