ios - 在避免状态的同时监视 UI 的最佳选择
问题描述
我对 Swift 和 iOS 开发相当陌生。我已经了解并渴望使用函数式编程来避免状态。因此,我正处于我旅程的一个阶段,我想问一个关于实现这一目标的编程技术的概念性问题。
假设我在由常规 UIViewController 控制的常规 UIView 上有一个常规 UISwitch。ViewController 类中的几个方法依赖于 UISwitch 的值来指示它们的精确操作。
我首先根据需要检查每个方法中的 UISwitch 的值,但是当这些方法在后台线程上异步调用时会导致警告。我知道我无法在后台线程上更改 UI,但似乎我也无法检查它的状态。
所以我求助于旧的最爱 - 类属性 - 来存储开关的当前状态,但感觉就像我这样做违背了函数式编程的基本原则。
然后,我意识到要让开关在应用程序关闭后用户离开时保持不变,我需要将其设置写入 UserDefaults。所以我可以在每次需要时从 UserDefaults 中获取值,但我担心的是,考虑到 iOS 需要来回切换到 UserDefaults,这种方法会相当慢。
所以,我的问题是:在我的 ViewController 的方法中获取 UISwitch 设置的最佳/最快/最不可能导致我未来问题的方法是什么?
- 每次需要检查开关时,通过调度到主线程来检查 UI
- 将值存储在类属性中,并挂起后果
- 每次需要时从 UserDefaults 获取值或
- 我尚未了解的任何其他方法
解决方案
你是对的,在某处坚持重要的用户选择是更好的用户体验。不过,您不必担心使用UserDefaults
它 - 它旨在用于存储那些简单的键值设置。此外,在您第一次加载它后,它不会使用物理内存 i/o - 您需要调用.synchronize
它以使其发生(例如,当应用程序进入后台时)。
我建议两种方法:
第一个对初学者更友好的方法是设置一个像这样的变量:
var yourFlag : Bool {
get {
let defaults = Defaults.standard
return defaults.bool(forKey: "yourFlagKey")
}
set (newValue) {
let defaults = Defaults.standard
defaults.set(newValue, forKey: "yourFlagKey")
}
}
这样你就可以像使用任何其他实例变量一样使用你的变量,但在引擎盖下它会使用UserDefaults
. 例如,在您的开关值更改操作中,您可以简单地设置新值,它将保持为UserDefaults
:
func onValueChanged(sender: UISwitch) {
yourFlag = !sender.on
}
我建议不要将此变量存储在您的 ViewController 中。我通常为我的所有用户设置创建一个容器类,这样我就可以在需要它们的任何地方检查它们。理想情况下,您希望将此容器作为UIViewController
.
第二种方法(如果你真的想更深入地研究函数式编程)是学习如何使用像 RxSwift 这样的 FRP(函数式反应式编程)框架,并将值变化事件视为可观察的,你可以在其上构建你的流程。但是,如果您刚刚开始,我建议您学习以常规(苹果)方式做事,以便您了解 FRP 带来的好处和缺点。
推荐阅读
- loops - 基本while循环的断言错误/异常
- ruby-on-rails - Rails - 包含一个模块而不使用包含这个词
- mysql - 使用 node.js MySQL 连接 ECONNREFUSED 仍然出现错误
- javascript - 在Javascript中将TZ日期格式转换为“dd/mm/yy hh:mm:ss”
- python - 如何将高度和宽度传递给 imagekit 模板标签?
- javascript - 如何在 React native 中显示包含用逗号分隔的图像 url 列表的字符串中的单个图像
- linux - 如何使用 Inotifywait 跟踪文件更改中的序列
- plotly - Plotly/Dash:如何防止动态插入的链接/元素在没有用户点击的情况下自动触发回调?
- jquery - TypeError:在使用 Jquery 数据表时,无法在 blazor clinet 应用程序中读取 null 的属性“removeChild”
- python - 在 plt.bar 中对值进行排序