ajax同步属性_创建一个同步的UserDefaults属性包装器

2023-10-17 14:10

本文主要是介绍ajax同步属性_创建一个同步的UserDefaults属性包装器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ajax同步属性

Since the birth of Swift’s property wrappers, I have seen numerous articles discussing how to create a wrapped variable that can persist itself to the UserDefaults sector. While many of the code examples suffice for the simplest case, I’ve still had some questions gnawing at the back of my head.

自Swift的属性包装器诞生以来,我已经看过许多文章,讨论如何创建一个包装的变量,该变量可以持久保存到UserDefaults部门。 尽管许多代码示例足以满足最简单的情况,但我仍然有些疑问仍然困扰着我。

  • If several of these instances would ever need to be alive at the same time, how will they synchronize?

    如果其中几个实例需要同时处于活动状态,它们将如何同步?
  • How do they synchronize if another process accesses the UserDefaults file, perhaps directly through the file system?

    如果另一个进程(可能直接通过文件系统)访问UserDefaults文件,它们如何同步?

In this article, we look at how to make a property wrapper that persists your variables in UserDefaults. They also stay on top of any value changes, regardless of where they originate.

在本文中,我们将研究如何制作一个属性包装器,以将变量保留在UserDefaults中。 无论它们来自何处,它们也始终处于任何价值变化之上。

分析一个简单的实现 (Analyzing a Simple Implementation)

Let’s take a look at a simple implementation of a property wrapper for persisting values in UserDefaults, to get a sense of what it does well and where it fails. We then use these realizations to build a wrapper that handles synchronization like a charm.

让我们看一下用于在UserDefaults中持久保存值的属性包装器的简单实现,以了解它的作用和失败之处。 然后,我们使用这些实现来构建一个包装,该包装像魅力一样处理同步。

The above is the most straightforward wrapper I’ve seen so far. It does not attempt to cache the currently persisted value; it merely relies on the caching mechanisms of UserDefaults. This solution is not terrible if that’s all you need. However, it becomes a headache as soon as you want to be able to reactively propagate changes out to, for example, a UI.

上面是到目前为止我所见过的最简单的包装器。 它不会尝试缓存当前持久化的值。 它仅依赖于UserDefaults的缓存机制。 如果这就是您所需要的,那么此解决方案并不可怕。 但是,一旦您希望能够以响应方式将更改传播到例如UI上,就会变得很头疼。

进行改进 (Making Our Improvements)

To be able to publish any changes made, we need to cache the value inside of our object. We can then listen to the notifications that UserDefault sends through NotificationCenter, and update our cached value whenever we receive one of those. This approach alleviates the problem of synchronization between multiple wrapper instances since each of them triggers a notification when they set a new value. It does, however, require us to switch from writing a struct to writing a class, since NotificationCenter can only register reference type objects.

为了能够发布所做的任何更改,我们需要将值缓存在对象内部。 然后,我们可以侦听UserDefault通过NotificationCenter发送的通知,并在收到其中之一时更新我们的缓存值。 这种方法减轻了多个包装器实例之间的同步问题,因为每个包装器实例在设置新值时都会触发通知。 但是,这确实需要我们从编写结构切换为编写类,因为NotificationCenter只能注册引用类型对象。

As we can see in the above implementation, we change a few things so that the object makes use of the cached value property. We also conform to the ObservableObject protocol and make use of Combine’s Published construct to let others react to any changes.

正如我们在上述实现中所看到的,我们做了一些更改,以便对象利用缓存的value属性。 我们还遵守ObservableObject协议,并利用Combine的Published结构让其他人对任何更改做出React。

The real improvement here is that the wrapper has a chance to react to any changes made through an instance of UserDefaults. Since all other wrapper objects go through UserDefaults, they are covered too.

真正的改进是包装器有机会对通过UserDefaults实例进行的任何更改做出React。 由于所有其他包装对象都通过UserDefaults,因此它们也被覆盖。

Does this mean that we are safe?Unfortunately not.

这是否意味着我们安全?

照顾意外地方的变化 (Taking Care of Changes From Unexpected Places)

What would happen if someone set a new value for our key from another process? Or updates the default values by writing straight to the property list file that holds them? With this implementation, we don’t have a way of handling that. It looks like we’ve spotted a potential improvement!

如果有人在另一个过程中为我们的密钥设置了新的值,将会发生什么? 还是直接写入保存默认值的属性列表文件来更新默认值? 使用此实现,我们没有一种处理方法。 看来我们已经发现了潜在的改进!

The UserDefaults property list is the least common denominator that may cause our wrappers or the UserDefaults instance to go out-of-sync. This file is a classic key-value list that can be read and written to, just like any other. To pick up on changes that originate from strange places, we need to monitor that list and react to any write operations that occur. To do that, we are going to engineer a FileWriteMonitor.

UserDefaults属性列表是最小公分母,它可能导致我们的包装器或UserDefaults实例不同步。 该文件是一个经典的键值列表,可以像其他任何文件一样被读取和写入。 要获取来自陌生地方的更改,我们需要监视该列表并对发生的所有写操作做出React。 为此,我们将设计一个FileWriteMonitor

There are probably many things going on in this piece of code that some may not have seen before. The FileWriteMonitor keeps a DispatchSourceFileSystemObject instance. That is a long word to describe an object that lets us observe events in a file descriptor.

在这段代码中可能发生了许多以前可能未曾看到的事情。 FileWriteMonitor保留一个DispatchSourceFileSystemObject实例。 这是一个很长的字眼,用来描述一个对象,它使我们可以观察文件描述符中的事件。

Speaking of which, our monitor also keeps track of a file descriptor. A file descriptor is a POSIX construct that allows us to get an abstract handle to access a file. It is this beauty, together with the DispatchSourceFileSystemObject, that is going to make magic for us.

说到这一点,我们的监视器还跟踪文件描述符。 文件描述符是POSIX构造,它使我们能够获取访问文件的抽象句柄。 正是这种美感与DispatchSourceFileSystemObject一起为我们带来了魔力。

Focus your attention on the .connectDispatchSource method. If we have obtained a file descriptor and created an event source before, we cancel and close them. These actions make sure we don’t leave a lot of loose ends hanging around.

将注意力集中在.connectDispatchSource方法上。 如果之前已经获得文件描述符并创建了事件源,则取消并关闭它们。 这些动作确保了我们不会留下很多松散的末端。

Once that is done, we obtain a new file descriptor for the file we are interested in. In our case, this is the UserDefaults property list file. From the descriptor, we create a new event source that will observe and propagate write and delete operations to us. In the event handler, we check for the event that triggered our handler. We reconnect our event source to a new file descriptor if we observe a delete event. If the event source passes us a write event, we call the onWrite closure that we got in the initializer.

一旦完成,我们将为感兴趣的文件获取一个新的文件描述符。在我们的例子中,这是UserDefaults属性列表文件。 从描述符中,我们创建一个新的事件源,它将观察并向我们传播写入和删除操作。 在事件处理程序中,我们检查触发了处理程序的事件。 如果观察到delete事件,我们会将事件源重新连接到新的文件描述符。 如果事件源向我们传递了一个写事件,我们将调用初始化程序中获得的onWrite闭包。

Now, let’s take this thing for a spin. Let’s see how we can use it to complete our property wrapper.

现在,让我们旋转一下。 让我们看看如何使用它来完成我们的属性包装器。

Pay special attention to the initializer in this piece of code. We first obtain a URL for the UserDefaults list, which we pass into our FileWriteMonitor together with a closure. That closure calls an update method which reads out the new value from the file and caches it. You may also notice that it passes the new value to UserDefaults, which allows it to update its cache and send a notification to the other property wrappers that may want to update their caches as well.

在这段代码中要特别注意初始化程序。 我们首先获取UserDefaults列表的URL,并将其与闭包一起传递到FileWriteMonitor 。 该闭包调用一个update方法,该方法从文件中读取新值并将其缓存。 您可能还会注意到,它将新值传递给UserDefaults,这使它可以更新其缓存并将通知发送给可能也要更新其缓存的其他属性包装器。

Image for post
Our final property wrapper at play!
我们最后的属性包装器正在发挥作用!

更多灵感 (More Inspiration)

In case you are interested to learn more, I post a fair share of articles. Feel free to follow me to get an update when there’s something new to read!

如果您有兴趣了解更多信息,我会发布很多文章。 有新内容要阅读时,请随时关注我以获取更新!

Until next time, you may be interested in reading about how to perform Monte Carlo simulations on a mobile device, or how to program in a protocol-oriented fashion. Below are links to those articles!

在下一次之前,您可能有兴趣阅读有关如何在移动设备上执行蒙特卡洛模拟或如何以面向协议的方式进行编程的信息。 以下是这些文章的链接!

Thanks for reading!

谢谢阅读!

翻译自: https://medium.com/swlh/creating-a-synchronized-userdefaults-property-wrapper-b2d9629b0aae

ajax同步属性


http://www.taodudu.cc/news/show-7979671.html

相关文章:

  • 区块链论文6(teether检测智能合约漏洞并自动生成漏洞路径)
  • 根据各工序时间画aoe网_干货 | 你知道建筑主体施工工序吗?(附:超详细流程图)...
  • 毛坯房装修顺序是怎样的 装修注意事项
  • Neo4j 桌面版的使用教程
  • 7.3.2 用管道匹配多个分组
  • C++内存管理及内存问题的分析
  • apt和dpkg包管理器
  • 内核态下基于动态感染技术的应用程序执行保护(五 动态感染)
  • 李彦宏的“罪己诏
  • 剪枝论文三( Sparse Structure Selection)
  • Transformer论文解读二(Vision Transformer)
  • 语义分割论文解读三(HRNetv1, HRNetv2)
  • 网络参数重组论文四(Diverse Branch Block)
  • 剪枝论文五(Connection pruning)
  • 网络参数重组论文二(ACNet,RepMLP)
  • 蒸馏论文十(Structured Knowledge Distillation for Dense Prediction)
  • 蒸馏论文四(Relational Knowledge Distillation)
  • Transformer论文解读三(distillation token)
  • 目标检测论文解读四(检测蒸馏论文三篇)
  • 蒸馏论文一(knowledge distillation)
  • Transformer论文解读五(Swin Transformer)
  • 网络参数重组论文一(RepVGG)
  • 目标检测论文解读五(YOLOF)
  • Transformer论文解读四(SegFormer)
  • 蒸馏论文二(Attention Transfer)
  • 网络参数重组经典论文
  • 语义分割经典论文详解
  • 剪枝论文四(ThiNet)
  • 蒸馏论文八(分类蒸馏论文八篇)
  • 知识蒸馏经典论文详解
  • 这篇关于ajax同步属性_创建一个同步的UserDefaults属性包装器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



    http://www.chinasem.cn/article/225921

    相关文章

    Spring Security基于数据库的ABAC属性权限模型实战开发教程

    《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

    AJAX请求上传下载进度监控实现方式

    《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

    CSS will-change 属性示例详解

    《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化

    idea中创建新类时自动添加注释的实现

    《idea中创建新类时自动添加注释的实现》在每次使用idea创建一个新类时,过了一段时间发现看不懂这个类是用来干嘛的,为了解决这个问题,我们可以设置在创建一个新类时自动添加注释,帮助我们理解这个类的用... 目录前言:详细操作:步骤一:点击上方的 文件(File),点击&nbmyHIgsp;设置(Setti

    Python 中的异步与同步深度解析(实践记录)

    《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

    浅析CSS 中z - index属性的作用及在什么情况下会失效

    《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

    Spring 中使用反射创建 Bean 实例的几种方式

    《Spring中使用反射创建Bean实例的几种方式》文章介绍了在Spring框架中如何使用反射来创建Bean实例,包括使用Class.newInstance()、Constructor.newI... 目录1. 使用 Class.newInstance() (仅限无参构造函数):2. 使用 Construc

    C#原型模式之如何通过克隆对象来优化创建过程

    《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

    Linux搭建Mysql主从同步的教程

    《Linux搭建Mysql主从同步的教程》:本文主要介绍Linux搭建Mysql主从同步的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux搭建mysql主从同步1.启动mysql服务2.修改Mysql主库配置文件/etc/my.cnf3.重启主库my

    JAVA SE包装类和泛型详细介绍及说明方法

    《JAVASE包装类和泛型详细介绍及说明方法》:本文主要介绍JAVASE包装类和泛型的相关资料,包括基本数据类型与包装类的对应关系,以及装箱和拆箱的概念,并重点讲解了自动装箱和自动拆箱的机制,文... 目录1. 包装类1.1 基本数据类型和对应的包装类1.2 装箱和拆箱1.3 自动装箱和自动拆箱2. 泛型2