在Swift中作为观察员的闭包

随着Swift进入编程领域,为开发人员打开了大门,使开发人员能够通过使事情变得简单和紧凑将其思想转化为Apple平台上的应用程序。 Swift引入了许多新功能和概念,但是在这篇文章中,我们将讨论Closures,这是当今iOS开发人员中非常有趣且最流行的编码实践之一。

根据Swift文档:

闭包是可以独立传递的功能块,可以在代码中传递和使用。

闭包不仅是Swift独有的,而且在Swift引入之前,它们就存在于其他编程/脚本语言中。 Swift中的闭包类似于C和Objective-C中的块以及其他编程语言中的lambda。

我们大多数人都不熟悉闭包,但是很长一段时间以来就在我们的代码中使用它们。 在我们日常的编码实践中,有一些实例我们间接使用了闭包,但我们对此并不了解。 以下是下面提到的几个示例:

  • 在第三方API的帮助下从服务器获取数据; 在这里,您不必等待数据任务完成并异步获取数据,并在收到响应后使用@escaping闭包将其还原。
  • 使用视图动画,因为某些功能需要异步执行。

闭包可以从定义它们的上下文中捕获和存储对任何常量和变量的引用。 这称为关闭这些常量和变量。 让我们快速看一下如何定义闭包:

  {(params)-> returnType in // statements} 

让我们来看看闭包表达式:

  let fullname:(String,String)-> String = {(firstName,lastName)返回firstName +“” + lastName} fullname(“ Prashant”,“ Gautam”)//结果为Prashant Gautam 

在上面的表达式中,闭包接受String类型的两个参数并将其连接起来并返回新的字符串。 闭包表达式中的参数可以是输入输出参数。 我们也可以使用可变参数,但您必须命名可变参数。 元组也可用作参数类型和返回类型。

注意: 闭包表达式语法中的参数不能具有默认值。

为了这篇文章的主题,我被限制不要过多地研究闭包。 您可以在此处找到有关闭包的广泛信息。

作为iOS开发人员,我们都知道NotificationsKVO 。 两者都用于通知多个对象,以响应应用程序或对象属性的某些更改。 让我们在闭包的帮助下创建自己的观察者。 相信我,将您自己的代码用于同一目的非常有趣。

让我们举一个基于UITabbar的应用程序的简单示例。 演示应用程序中有两个选项卡。 在第一个选项卡上,我们有一个按钮,该按钮触发更新以将新消息反映给作为观察者添加的所有对象。

首先,我们创建一个基于标签栏的应用程序,并在FirstViewController内添加一个按钮“ Update ”,以触发更新的消息。 为此按钮添加操作updateAction(_ sender:Any)

现在该创建我们的Observer类了。 因此,添加一个名为Observer.swift的新文件 我们将把这一节作为单例。

 类Observer {// MARK:-Singleton实例类var共享:Observer {struct Singleton {静态let instance = Observer()}返回Singleton.instance} private init(){}} 

现在准备该类以添加观察者。

 私人var _observers = [(AnyObject?,(String)-> Void)]() 

一旦触发任何更新,上面的观察者数组将添加要观察或更新的对象。 该数组由对象引用和元组中的闭包组成。 闭包将接受字符串值作为参数,并且不会返回,因此返回类型将为Void。

现在创建一个辅助函数,该函数将在Observer数组中绑定/插入我们的类对象。

 函数绑定(_观察者:AnyObject ?, _闭合:@逃逸(字符串)->无效){如果!_observers.contains(其中:{$ 0.0 ===观察者}){_observers.append((观察者,闭合))} } 

此功能有两个参数–

观察者:需要通知类对象。

闭包:触发任何更新时调用。

首先,我们必须验证对象是否已经添加到观察者数组中,否则,我们将其附加到数组中。

现在添加另一个函数,该函数将触发更新并通知在观察者数组中添加的所有对象。

  func update(message:String){用于_observers中的观察者{observer.1(message)}} 

我们将遍历观察者数组的每个元素,并通过传递要显示的消息来调用闭包。 数组中每个元组的第一个索引访问每个观察者的闭包,即; 观察者。 1 (消息)。

完成了吗 我们错过了什么吗? 哦,如果有人要删除观察者,该怎么办。 让我们在Observer.swift类中创建一个函数,它将为我们完成此任务。

  func removeObserver(_ object:AnyObject){对于_observers中的观察者,var index = 0 {如果Observer.0 ===对象{_observers.remove(at:index)break} index + = 1}} 

但是请确保您应该谨慎使用此方法,例如:如果我们在viewWillDisappear内部使用此方法,则您的代码将不再接收更新。 在此示例中,由于我们正在更新标签栏的初始视图控制器,因此此功能没有这种用途。

现在是时候将我们的观察者实现到视图控制器中了。

在这里,我们通过传递self和,将视图控制器对象与观察者绑定 从闭包回调中获取更新的消息。 捕获列表中的[weak self]将避免任何保留周期,因为我们在块内使用self。 同样,将在SecondViewController中添加相同的代码

现在该更新我们的操作方法了,第一个视图控制器的完整代码将如下所示。

现在运行您的项目,然后点击第二个选项卡,以便初始化第二个视图控制器。 点击更新按钮,您将看到两个视图控制器上的消息标签将更新为新消息“ Hello”

Jouir de!

在这里,我们完成了自己的观察者的创建。 他们还有很多空间可以改善这种模式。 您愿意分享您的建议,我很乐意在同一same的评论中进行对话。

我希望您喜欢阅读这篇文章,请分享并推荐它,以便其他人可以找到它💚!

你可以在Medium上关注我 有关最新文章。 在LinkedIn上与我联系