Tag: viewmodel

RxSwift视图模型的剖析

视图控制器中使用每个属性来驱动UI行为。 在此示例中,每个输入和输出都是一个Driver ,因此强烈建议使用Driver ,因为Driver始终在主线程上运行,永远不会完成,并且永远不会产生错误事件。 这使得视图控制器对那些Driver具有非常简单的响应。 将视图模型连接到视图控制器 看一下将这些Driver绑定到UI控件有多么简单: DisposeBag ,在新版本的RxSwift中,可以使用更好的样式将Disposable插入DisposeBag中。 现在,您可以使用相同的代码块执行以下操作: 视图模型初始化器 关于该视图模型的下一件要注意的事情是,使用格式正确的元组将输入和依赖项传递到初始化程序的简洁方法。 这种样式无疑使视图模型的输入是什么,并且还提供了对任何依赖项的清晰声明。 Zaher在评论中指出,在init方法的主体中, 一切都只是一个定义。 从输入序列到输出序列的纯转换。 该引言总结了MVVM视图模型最重要的一个方面: 将 输入序列转换为输出序列。 需要注意的另一件事:类上没有其他方法。 一切都在init函数中发生。 相反, SearchResultViewModel是确实具有实例方法的视图模型的示例。 让我们看一下这如何影响init的设计。 因为init方法在初始化所有属性之前无法访问self,并且因为他想在self上使用这些方法来准备imageURL和title输出,所以他被迫为它们提供一个临时值,然后用实际输出覆盖它们。 我不推荐这种方法。 在视图模型上避免实例方法 视图模型上的实例方法只会增加内存泄漏的风险。 这些方法的任何调用都需要引用self。 您必须非常小心, 不要 在闭包内部使用实例方法 。 Zaher不在任何闭包内使用它们,因此SearchResultViewModel没有泄漏。 但是我会争辩说,即使为此使用实例方法也为意外的内存泄漏打开了大门。 如在此重构版本中一样,最好使用文件专用顶级功能。 最终结果是GithubSignupViewModel2.init充当静态函数。 将其输出连接到控件后,不再需要返回的GithubSignupViewModel2实例。 输出将保留在内存中直到被处置,但视图模型实例本身已被释放。 这样可以确保没有内存泄漏。 视图模型可以是不变的结构 GithubSignupViewModel2可以很容易地成为一个struct 。 实际上,将其更改为一个struct ,它仍然可以编译并运行。 由于您只需要一个实例,并且由于其所有属性都是不可变的,因此对于此视图模型而言,实际上更喜欢使用struct 。 视图模型可以是一个功能 因为我们可以并且应该设计视图模型以在init方法内部完成所有输入到输出的转换,所以我们实际上只需要一个函数。 在下面的要点中,我将视图模型重构为顶级功能。 没课。 没有结构。 只是一个功能。 这是您可以粘贴在RxExample项目中的要点,以替换原始的GitHubSignupViewController2 ,然后编译并运行。 […]

iOS中使用MVVM

我是一个iOS开发人员,我在我的项目中拥有大量视图控制器,所以我一直在寻找一种更好的方式来构build我的项目,并遇到了MVVM(Model-View-ViewModel)架构。 我已经阅读了很多与iOS的MVVM,我有几个问题。 我会用一个例子来解释我的问题。 我有一个名为LoginViewController的视图控制器。 LoginViewController.swift import UIKit class LoginViewController: UIViewController { @IBOutlet private var usernameTextField: UITextField! @IBOutlet private var passwordTextField: UITextField! private let loginViewModel = LoginViewModel() override func viewDidLoad() { super.viewDidLoad() } @IBAction func loginButtonPressed(sender: UIButton) { loginViewModel.login() } } 它没有Model类。 但是我创build了一个名为LoginViewModel的视图模型来放置validation逻辑和networking调用。 LoginViewModel.swift import Foundation class LoginViewModel { var username: String? var password: String? init(username: […]