实现RxSwift与Swift委托

委托是一种常用的设计模式,它允许一个对象通过协议将工作移交给另一个对象(可能是不同类型)。

另一方面, 反应式编程围绕应用程序生态系统中变化的扩散而进行的数据流和传输。 这是通过观察者,可观察对象和调度程序完成的,观察者在调度程序告诉它们运行的​​线程上寻找可观察对象的发射。


James Rochabrun的文章“在Swift中逐步实现委托”是我阅读的关于委托的第一篇文章之一。

这是一个使用两个视图控制器A和B的简单应用程序。视图控制器A符合视图控制器B的委托协议,其中视图控制器B告诉A显示用户选择的颜色。

我将使用James的委托示例与使用响应式编程(RxSwift)的相同实现进行比较。


  // 1 
覆盖func prepare(对于segue:UIStoryboardSegue,发件人:任何?){如果让nav = segue.destination为? UINavigationController,让viewControllerB = nav.topViewController为? ViewControllerB {// 2
viewControllerB.delegate = self}} // 3
func changeBackgroundColor(_ color:UIColor?){view.backgroundColor = color}

此代码块在ViewControllerA.swift

//1当用户单击“显示视图控制器B”时,将调用该代码以准备该序列。

//2由于在此代码块中有对ViewControllerB的引用,因此我们将B的委托变量分配给self ,即ViewControllerA

 协议ViewControllerBDelegate:类{ 

func changeBackgroundColor(_ color:UIColor?)}

接下来,在ViewControllerB.swift文件中,声明ViewControllerB.swift的协议,该协议包含更改View Controller A中背景颜色的功能。

  // 1 
弱var委托:ViewControllerBDelegate?// 2
@objc func handleTap(_ tapGesture:UITapGestureRecognizer){// 3
view.backgroundColor = tapGesture.view?.backgroundColor // 4
委托?.changeBackgroundColor(tapGesture.view?.backgroundColor)}

//1ViewControllerB类中,我们声明一个弱类变量delegate ,其中包含对委托View Controller A的引用。

//2当用户点击其中一个按钮以更改颜色时…

//3我们将首先更改当前视图(视图控制器B)的颜色。

//4然后调用delegate协议函数以更改View Controller A中的背景颜色。

**自己运行代码- 源代码

在RxSwift中,可以通过可观察的序列来发送数组,字典和字符串形式的数据。 另一个类或对象可以预订发出的序列。

  var changeBackgroundColor:Observable  = BehaviorSubject(值:.cyan) 

让我们从ViewControllerB开始,在其中设置要发出的变量changeBackgroundColor 。 这将是Observable类型的类变量。

接下来,我们想在点击按钮时发出一个新变量。

  @objc func handleTap(_ tapGesture:UITapGestureRecognizer){view.backgroundColor = tapGesture.view?.backgroundColor // 1 
守卫let newBackgroundColor = view.backgroundColor else {return} // 2
(changeBackgroundColor as?BehaviorSubject)?. onNext(newBackgroundColor)}

//1当用户点击按钮更改背景颜色时,我们首先要确保选择了新的背景颜色

//2接下来,将可观察对象作为BehaviorSubject发出

订阅后,行为主体将仅提供序列中的最新元素。 还有其他类型的主题,例如PublishSubjectReplaySubjectVariables ,每个主题在订阅时都提供独特的行为。 (请参阅下面的参考资料)

发射后,将通知所有订阅此可观察对象的对象。 您可能会看到我们现在要进行的工作。

 覆盖func prepare(对于segue:UIStoryboardSegue,发件人:任何?){如果让nav = segue.destination为?  UINavigationController,让viewControllerB = nav.topViewController为?  ViewControllerB {viewControllerB.changeBackgroundColor // 1 
.subscribe(onNext:{// 2中的[[weak self] newBackgroundColor
self?.changeBackgroundColor(newBackgroundColor)
})// 3
.disposed(作者:disposeBag)}
}

//1回到ViewControllerA ,我们要订阅ViewControllerB changeBackgroundColor的可观察的changeBackgroundColor

//2收到序列后,我们将更改View Controller A的背景颜色。请注意, //2处的代码要等到发出可观察对象后才能运行。

//3通过在订阅上使用dispose终止观察到的序列。 这将释放分配用于计算任何新元素的资源。

当我们点击关闭以返回到View Controller A时,我们将看到背景颜色已更改为View Controller B中的选定颜色。 😮

RxSwift或Swift委托-哪种方法最好跨类发送数据?

根据项目的性质,您可能需要考虑使用RxSwift而不是委托。 RxSwift以编写更少的代码,更好的可读性而著称,并且总体而言非常适合UI相关操作的异步和多线程工作。 尽管安装了RxSwift是您可能要考虑的依赖项。

我以前在项目中亲自使用了委托和RxSwift,我必须说我比委托更喜欢RxSwift。 RxSwift(通常)具有较少的代码,对我来说更直观。 RxSwift肯定有一条学习曲线,可观察的单元测试和序列可能很棘手。 但绝对值得长期学习。

RxSwift教程的源代码

代表教程的源代码

有关RxSwift的更多资源,请查看Sebastian Boldt的文章:在10分钟内学习和掌握RxSwift的基础知识(我发现它非常有用)以及RxSwift的Github回购以了解更多信息。


您已完成本文的结尾-感谢您的阅读! 如果喜欢的话,请给它鼓掌👏🏻和评论a。

在LinkedIn上与我联系,打个招呼! 👋🏼