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

    相关文章

    MySQL 用户创建与授权最佳实践

    《MySQL用户创建与授权最佳实践》在MySQL中,用户管理和权限控制是数据库安全的重要组成部分,下面详细介绍如何在MySQL中创建用户并授予适当的权限,感兴趣的朋友跟随小编一起看看吧... 目录mysql 用户创建与授权详解一、MySQL用户管理基础1. 用户账户组成2. 查看现有用户二、创建用户1. 基

    Python打印对象所有属性和值的方法小结

    《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

    Python中使用uv创建环境及原理举例详解

    《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

    canal实现mysql数据同步的详细过程

    《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

    CSS3中的字体及相关属性详解

    《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字

    Java中实现线程的创建和启动的方法

    《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

    Linux实现线程同步的多种方式汇总

    《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

    SpringBoot读取ZooKeeper(ZK)属性的方法实现

    《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

    Java反射实现多属性去重与分组功能

    《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

    Mysql的主从同步/复制的原理分析

    《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意