这个Swift代码做了什么:var greetingDidChange:((GreetingViewModelProtocol) - >())?

时间:2016-10-29 23:33:59

标签: ios swift mvvm protocols

我已经对此做了很多研究,所以我会告诉你我认为它做了什么,然后希望有人可以告诉我它实际上做了什么

我试图通过学习教程(link)来理解MVVM模式。我会把所有代码都放在这里以防万一有人想把它放到Xcode中。

我的视图模型名为GreetingViewModel,它采用协议并包含我不理解的这行代码:

protocol GreetingViewModelProtocol: class {      
  var greeting: String? { get }
  var greetingDidChange: ((GreetingViewModelProtocol) -> ())? { get set }
  init(person: Person)
  func showGreeting()
}

class GreetingViewModel : GreetingViewModelProtocol {
  let person: Person
  var greeting: String? {
    didSet {
      self.greetingDidChange?(self)
    }
  }

  // what does line do???
  var greetingDidChange: ((GreetingViewModelProtocol) -> ())?

  required init(person: Person) {
    self.person = person
  }

  @objc func showGreeting() {
    self.greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
  }
}

在视图控制器(下面)中,当self.viewModel = viewModel执行时,它会在var viewModel的属性观察者中运行代码。然后将函数(GreetingViewModelProtocol) -> ()分配给var greetingDidChange

class GreetingViewController : UIViewController {
  let showGreetingButton = UIButton()
  @IBOutlet weak var greetingLabel: UILabel!

  var viewModel: GreetingViewModelProtocol! {
    didSet {
      self.viewModel.greetingDidChange = { [unowned self] viewModel in
        self.greetingLabel.text = viewModel.greeting
      }
    }
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
  }

  override func viewDidLoad() {
    super.viewDidLoad()

    let model = Person(firstName: "David", lastName: "Blaine")

    let viewModel = GreetingViewModel(person: model)

    self.viewModel = viewModel

    showGreetingButton.backgroundColor = UIColor.red
    showGreetingButton.tintColor = UIColor.black
    showGreetingButton.setTitle("Show Greeting", for: .normal)
    showGreetingButton.addTarget(self.viewModel, action: #selector(GreetingViewModel.showGreeting), for: .touchUpInside)

    showGreetingButton.translatesAutoresizingMaskIntoConstraints = false    
    view.addSubview(showGreetingButton)
    let buttonTop = NSLayoutConstraint(item: showGreetingButton, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.greaterThanOrEqual, toItem: view, attribute: NSLayoutAttribute.topMargin, multiplier: 1.0, constant: 20)
    let buttonLeading = NSLayoutConstraint(item: showGreetingButton, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.leadingMargin, multiplier: 1.0, constant: 0.0)
    showGreetingButton.contentEdgeInsets = UIEdgeInsetsMake(2, 2, 2, 2)
    NSLayoutConstraint.activate([buttonTop, buttonLeading])
  }
}

此时,我相信这只是表示greetingDidChange拥有一个函数,该函数接受采用GreetingViewModelProtocol协议的任何类对象并且不返回任何内容。 UI完成加载,看起来像这样:

enter image description here

当我点击显示问候语按钮时,会调用GreetingViewModel.showGreeting(),然后执行var greeting上的属性观察者(self.greetingDidChange?(self))将GreetingViewModel发送到此神秘的代码行我不明白。

这会导致此属性观察者执行:

  var viewModel: GreetingViewModelProtocol! {
    didSet {
      self.viewModel.greetingDidChange = { [unowned self] viewModel in
        self.greetingLabel.text = viewModel.greeting
      }
    }
  }

然后执行其余代码并显示消息:

enter image description here

我认为因为viewModelGreetingViewModelvar viewModel属性观察者中的闭包设置为self.greetingLabel.text = GreetingViewModel.greeting。在我的神秘代码行var greetingDidChange: ((GreetingViewModelProtocol) -> ())?viewModel.didSet中的代码之间似乎存在某种关系,但它会让我感觉它是如何工作的。

我是否接近,有人会善意向我解释这里发生了什么?

另外,我的简单模型是:

struct Person {
  let firstName: String
  let lastName: String
}

0 个答案:

没有答案