передает аргумент модель представления или протокол

Коды взяты из протокольно-ориентированного MVVM, и это как ViewModel выглядит :

struct MinionModeViewModel: SwitchWithTextCellDataSource {
    var title = "Minion Mode!!!"
    var switchOn = true
}

extension MinionModeViewModel: SwitchWithTextCellDelegate {
    func onSwitchTogleOn(on: Bool) {
        if on {
            print("The Minions are here to stay!")
        } else {
            print("The Minions went out to play!")
        }
    }
    
    var switchColor: UIColor {
        return .yellowColor()
    }
}

Я понимаю эту часть. По сути, MinionModeViewModel переопределяет поведение по умолчанию SwitchWithTextCellDelegate и SwitchWithTextCellDelegate .

Затем автор настраивает ячейку, передавая viewModel в качестве аргументов:

SettingsViewController.swift

let viewModel = MinionModeViewModel()
cell.configure(withDataSource: viewModel, delegate: viewModel)
return cell

Однако в SwitchWithTextTableViewCell аргументами метода configure являются SwitchWithTextCellDataSource и SwitchWithTextCellDelegate.

func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?) {
        self.dataSource = dataSource
        self.delegate = delegate
        
        label.text = dataSource.title
        switchToggle.on = dataSource.switchOn
        // color option added!
        switchToggle.onTintColor = delegate?.switchColor
    }

Я новичок в Swift. Может кто-нибудь объяснить

  1. каковы названия и их значение dataSource и delegate configureметода в SwitchWithTextTableViewCell . Они External Parameter Names.

  2. почему тип передаваемых аргументов метода configure отличается: типы view model и protocols


person tonytran    schedule 07.06.2016    source источник


Ответы (2)


Прежде всего, MinionModeViewModel не переопределяет поведение SwitchWithTextCellDelegate и SwitchWithTextCellDelegate по умолчанию.

Термин переопределение используется вместе с наследованием. Пример

class A {
  func someFunction() {
  }
}
class B:A {
  override func someFunction() {
  }
}

Здесь класс B является подклассом класса A, и поэтому, если класс B должен предоставлять другую реализацию метода someFunction, чем его класс A, он должен переопределить его и предоставить другую реализацию.

Протоколы разные. Это своего рода абстрактный класс. Протоколы — это просто набор правил. Поэтому, когда какой-либо класс или структура соответствуют протоколу, это означает, что они должны реализовать все необходимые методы или свойства, указанные в определении протокола.

Пример:

protocol SwitchWithTextCellDelegate {

  func onSwitchTogleOn(on: Bool)

  var switchColor: UIColor {get}
}

Теперь любая структура или класс, соответствующие протоколу SwitchWithTextCellDelegate, должны реализовывать метод onSwitchToggleOn, а также иметь свойство switchColor, которое будет иметь геттер.

Как вы сделали:

extension MinionModeViewModel: SwitchWithTextCellDelegate {
    func onSwitchTogleOn(on: Bool) {
    }

    var switchColor: UIColor {
        return someColor
    }
}

Объяснение метода

1. func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?)

dataSource: в этом параметре мы можем передать любой класс или структуру, которая соответствует протоколу SwitchWithTextCellDataSource.

делегат: в этом параметре мы можем передать любой класс или структуру, соответствующую протоколу SwitchWithTextCellDelegate.

Теперь может сбить с толку то, что автор учебника передал один и тот же объект в обоих параметрах. Почему бы не передать его как один параметр?

let viewModel = MinionModeViewModel()
cell.configure(withDataSource: viewModel, delegate: viewModel)

Это потому, что здесь MinionModeViewModel соответствует протоколам SwitchWithTextCellDataSource и SwitchWithTextCellDelegate, поэтому мы можем передавать один и тот же объект в обоих параметрах. Но этот метод может передавать любой объект, соответствующий этим протоколам.

person Prajeet Shrestha    schedule 07.06.2016

Протоколы определяют поведение, реализуемое адаптирующими объектами (обычно они не перезаписывают поведение).

В этом примере SwitchWithTextCellDataSource и SwitchWithTextCellDelegates — это protocols, которые MinionModelViewModel унаследовали (усыновили). Чтобы это имело больше смысла, подумайте, что у вас может быть другая структура:

struct EvilVillanViewModel: SwitchWithTextCellDataSource {
  var title: "Evil Villian Model!!!"
  var switchOn = false
}

Поскольку эта структура также принимает SwitchWithTextCellDataSource, она взаимозаменяема везде, где код ожидает class/struct, реализующего SwitchWithTextCellDataSource, потому что он знает, что у него будет заголовок и значение switchOn, потому что этого требует протокол. Без него ваш код не скомпилируется.

Итак.... в configure(withDataSource dataSource: SwitchWithTextCellDataSource...) вы могли бы так же легко передать структуру EvilVillanViewModel или MinionModelViewModel, и все будет работать отлично. Когда блок кода ссылается на dataSource.title, он знает, что все, что вы ему передали, имеет title, потому что это должно было соответствовать протоколу SwitchWithTextCellDataSource.

И это только начало силы протоколов! Надеюсь это поможет!

person DJohnson    schedule 07.06.2016