在过去的两年里,我使用MVVM模式构建应用程序,每个教程都说MVVM使用反应库,例如: RXSwift或ReactiveCocoa,因为我是iOS程序员。我才意识到
我只知道Reactive是函数式编程,这意味着声明性编程。
发布于 2018-06-03 05:54:33
对我来说,单独使用委托似乎是实现应用程序逻辑的最长方式。响应式的方法更简洁,需要的代码更少,而且是一种非常强大的工作方式。
例如,假设您想使用RxSwift/RxCocoa和swift 4创建一个反应式ButtonTap系统:
1)创建一个协议,该协议的实现方式与创建普通委托抽象类的方式相同。请注意,我们遵循@objc
import RxSwift
import RxCocoa
// MARK: - ButtonTap Delegate protocol
@objc public protocol ButtonTapDelegate: NSObjectProtocol {
@objc func button(didSelect view: UIView, at index: Int)
}
2) DelegateProxyType类是响应式事件发生的地方。就像你从你的委托(ButtonTapDelegate)派生一个类一样,这个类不仅可以做到这一点,而且还可以使用PublishSubject来处理你的委托消息。
// MARK: - ButtonTap DelegateProxy
open class ButtonTapDelegateProxy: DelegateProxy<UIView, ButtonTapDelegate>,
DelegateProxyType, ButtonTapDelegate {
/// Typed parent object.
public weak private(set) var buttonView: UIView?
internal var didSelectSubject = PublishSubject<(view: UIView, index: Int)>()
// MARK: - parent object for delegate proxy.
public init(parentObject: UIView) {
self.buttonView = parentObject
super.init(parentObject: parentObject, delegateProxy: ButtonTapDelegateProxy.self)
}
// MARK: - Register known implementationss. (from DelegateProxyType)
public static func registerKnownImplementations() {
self.register { ButtonTapDelegateProxy(parentObject: $0) }
}
// MARK: - read the current delegate. (from DelegateProxyType)
public class func currentDelegate(for object: UIView) -> ButtonTapDelegate? {
return object.delegate
}
// MARK: - set the current delegate. (from DelegateProxyType)
public class func setCurrentDelegate(_ delegate: ButtonTapDelegate?, to object: UIView) {
object.delegate = delegate as? ButtonTapDelegateProxy
}
// MARK: delegate method
public func button(didSelect view: UIView, at index: Int) {
didSelectSubject.onNext((view, index))
}
// MARK: - dispose the publish subject
deinit {
didSelectSubject.on(.completed)
}
}
3)然后,简单地创建您的自定义按钮类,其中您有委托属性。您可以简单地通过调用其抽象方法将消息传递给您的委托。
// MARK: - create Custom ButtonView class with the delegate property
open class ButtonView: UIView {
@IBOutlet weak open var delegate: ButtonTapDelegate?
func tapButtonAction() {
let view = UIView()
let index = 2
delegate.button(didSelect: view, at: index)
}
}
// MARK: - ButtonView must have delegate property
extension ButtonView: HasDelegate {
public typealias Delegate = ButtonTapDelegate
}
4)您可以使用RxCocoa捕获由您的代理发送的消息。您只需要使用视图的这个扩展(ButtonView)从DelegateProxy类中引用您的PublishSubject。请注意,扩展是反应式的。
// MARK: - Custom ButtonView with the Reactive delegate and its protocol function
public extension Reactive where Base: ButtonView {
/// Reactive wrapper for `delegate`.
/// For more information take a look at `DelegateProxyType` protocol documentation.
fileprivate var delegate: ButtonTapDelegateProxy {
return ButtonTapDelegateProxy.proxy(for: base)
}
public func setDelegate(_ delegate: ButtonTapDelegate) -> Disposable {
return ButtonTapDelegateProxy
.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base)
}
public var didSelect: ControlEvent<(view: UIView, index: Int)> {
return ControlEvent(events: delegate.didSelectSubject)
}
}
5)在您的ViewController中,您可以使用RxSwift监听任何按钮点击,并在DelegateProxy类中捕获由PublishSubject发送的那些事件。这与RxSwift手势示例没有什么不同:https://github.com/RxSwiftCommunity/RxGesture
class myViewController: UIViewController {
@IBOutlet weak var buttonView: ButtonView!
override func viewDidLoad() {
super.viewDidLoad
buttonView.rx.didSelect.asObservable()
.subscribe(onNext: { view, index in
// button tapped in view at index
}).disposed(by: bag)
}
}
这个过程非常类似于所有的RxSwift和RxCocoa响应式委托的工作方式,它们已经在许多UIKit元素上实现了,比如:https://github.com/ReactiveX/RxSwift/tree/master/RxCocoa/iOS
反应式是非常灵活和强大的,不需要一直调用委托方法和设置委托。这只会发生一次,想象一下如何在viewController中处理CustomViews的不同组合。
https://stackoverflow.com/questions/45955694
复制相似问题