gpt4 book ai didi

ios - 有什么代表比 Reactive 做不到的?

转载 作者:行者123 更新时间:2023-12-01 18:39:17 31 4
gpt4 key购买 nike

在过去的两年里,我使用 MVVM 模式构建应用程序,并且每个教程总是说 MVVM 使用 Reactive 库,例如:RXSwift 或 ReactiveCocoa,因为我是 iOS 程序员。我才发现

  1. 为什么我们需要使用 Reactive,为什么我们不只使用委托(delegate)?
  2. 什么委托(delegate)不能超过 Reactive?
  3. 每种模式的优缺点?

我只知道 Reactive 是函数式编程,意思是声明式编程。

最佳答案

对我来说,单独使用委托(delegate)似乎是实现应用程序逻辑的最长方法。响应式更简洁,需要更少的代码,是一种非常强大的做事方式。

举个例子,假设你想使用 RxSwift/RxCocoa 和 swift 4 创建一个 Reactive ButtonTap 系统:

1) 您创建一个协议(protocol),其实现方式与创建普通委托(delegate)抽象类时的方式相同。请注意,我们符合@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 类是 react 性事件发生的地方。就像您从委托(delegate) (ButtonTapDelegate) 派生类一样,此类不仅会执行此操作,还会使用 PublishSubject 处理委托(delegate)消息。

// 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) 然后,只需创建您具有委托(delegate)属性的自定义按钮类。您可以通过调用其抽象方法将消息简单地传递给您的委托(delegate)。

// 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 捕获您的委托(delegate)发送的消息。您只需要使用 View 的这个扩展 (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 监听任何按钮点击并捕获由 PublishSubject 在您的 DelegateProxy 类中发送的那些事件。这与 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 Reactive delegates 的工作方式非常相似,它们已经在许多 UIKit 元素上实现了,如下所示:https://github.com/ReactiveX/RxSwift/tree/master/RxCocoa/iOS

响应式非常灵活和强大,不需要一直调用委托(delegate)方法和设置委托(delegate)。这只会发生一次,想象一下如何在 viewController 中处理 CustomViews 的不同组合。

关于ios - 有什么代表比 Reactive 做不到的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45955694/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com