在RxSwift框架里用到很多的开发模式和思维模式,其中的一个就是中介者模式。
什么是中介者模式?
一种设计模式。用一个中介对象来封装一系列对象的交互,从而把一批原来可能是交互关系复杂的对象转换成一组松散耦合的中间对象,以有利于维护和修改。
简单来说,可以理解为把交互关系复杂的代码封装在一个类里完成。用一个例子来说明一下:
class ViewController: UIViewController {
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
self.timer = Timer.init(timeInterval: 1, target: self, selector: #selector(test), userInfo: nil, repeats: true)
RunLoop.current.add(self.timer!, forMode: .common)
}
@objc func test(){
print("无法释放")
}
deinit {
self.timer?.invalidate()
self.timer = nil
}
}
本来是在ViewController
里实现Timer
,而且存在无法释放的问题,然后修改为:
class ViewController: UIViewController {
let proxy = TimerProxy()
override func viewDidLoad() {
super.viewDidLoad()
proxy.scheduledTimer(timeInterval: 1, target: self, selector: #selector(test), userInfo: nil, repeats: true)
}
@objc func test(){
print("中介者")
}
deinit {
print("ViewController释放了")
}
}
class TimerProxy: NSObject {
weak var target: NSObjectProtocol?
var sel: Selector?
var timer: Timer?
override init() {
super.init()
}
func scheduledTimer(timeInterval timeInterval: TimeInterval, target aTarget: Any, selector aSelector: Selector, userInfo: Any?, repeats repeats: Bool){
self.timer = Timer.init(timeInterval: timeInterval, target: self, selector: aSelector, userInfo: userInfo, repeats: repeats)
RunLoop.current.add(self.timer!, forMode: .common)
self.target = aTarget as? NSObjectProtocol
self.sel = aSelector
guard self.target?.responds(to: self.sel) == true else{
return
}
//为了判断target是否释放
let method = class_getInstanceMethod(self.classForCoder, #selector(timerFire))
class_replaceMethod(self.classForCoder, self.sel!, method_getImplementation(method!), method_getTypeEncoding(method!))
}
@objc private func timerFire(){
if self.target != nil{
self.target!.perform(self.sel)
}
else{
self.timer?.invalidate()
self.timer = nil
}
}
//做容错处理
override func forwardingTarget(for aSelector: Selector!) -> Any? {
if self.target?.responds(to: self.sel) == true {
return self.target
}
else{
return super.forwardingTarget(for: aSelector)
}
}
deinit {
print("TimerProxy释放了")
}
}
这就是中介者,在RxSwift里有很多中介者,比如之前分析KVO时的_RXKVOObserver
:
中介者模式是很经常用到的开发模式,可以使我们的代码变得简洁和解耦,也便于处理和维护,相信很多朋友就算不知道这个模式,但是在开发中也曾经不知不觉地用到过这种模式。