Pull to refresh
9
0

User

Send message
Спасибо за развернутый ответ!
Вы навели меня на VIPER, теперь изучаю этот подход. К сожалению, он довольно молодой, все статьи в гугле не старше года-двух, и материалов действительно очень мало, в особенности — конкретных примеров.
BepTep Спасибо за ваши посты! Очень интересно! Жду продолжения. Пожалуйста, ответьте на вопрос от начинающего. :) Вопрос относится к этой вашей иллюстрации:

Правильно ли я понимаю, что подразумевается передача данных в методе prepareForSegue? Дело в том, что мне очень не нравится яблочный паттерн «сегвеев», но может быть, я чего-то не понимаю, а вы с вашим более обширным опытом как раз меня переубедите. :)
Смотрите сами (сорри только на свифте умею):
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    switch segue.identifier! {
    case "showAccountDetails":
        let vc = segue.destinationViewController as AccountDetailsViewController
        vc.accountId = self.selectedAccount.accountId
    ...
    }
}

Недостаток 1: один метод на все случаи — с большим свичем внутри
Недостаток 2: первый VC должен знать не только конкретную имплементацию следующего (класс AccountDetailsViewController), но и уметь правильно его сетапить (accountId) — нарушена та самая обособленность контроллеров
Недостаток 3: на самом деле, элементарное поведение «перейти в AccountDetails» разбито на две части в совершенно разных местах контролера, так как помимо сниппета внутри prepareForSegue нам нужно было засетить selectedAccount внутри accessoryButtonTapped, и там же, собственно, вызвать performSegueWithIdentifier. Жуть!!! Код был бы гораздо читабельнее, если бы все это в одном месте, а именно accessoryButtonTapped
Недостаток 4: В обоих местах мы захардкодили одну и ту же стрингу с айдишником сегвея — плохо. Либо — что тоже плохо — мы загрязнили свой контроллер какой-то левой константой, которая де факто вообще не про этот контроллер, а про сториборд, в котором сидит его nib.

Все это мне кажется чрезмерной платой за
Достоинство 1: наглядная стрелочка в XCode с формочкой аттрибутов.
При этом, на самом деле в больших story это вовсе не наглядно, а превращается в стремное спагетти, особенно с суррогатными пустыми контроллерами из RBStoryboardLink. :)

Как быть?? Я предлагаю как раз между контроллерами и Service Layer вместить еще один слой делегатов, отвечающий за правильную настройку переходов:
func tableView(tableView: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath) {
    delegate.didRequestDetailsForAccount(accounts[indexPath.row])
}

Таким образом, снимаем груз ответственности с первого VC, делая его по-настоящему обособленным: все, что он должен уметь — это показать список аккаунтов и дернуть делегат в нужный момент, мол, юзер хочет видеть details. Как вы думаете, такой подход имеет право быть?
Круто! Спасибо за пост! Только не читавшему пост юзеру не понятно, как играть (я сначала скачал, потом читал). :)
А можно наивный вопрос, насколько сложно сделать OSX-порт?
Я попробовал, вроде все блоки передаются спокойно!)
class Test {
    typealias T = (()->Void)
    func test(foo:T) {}
    let foo1:T = { }
    init () {
        let foo2:T = {}
        test(foo1)
        test(foo2)
    }
}

Ошибок нет
inout — работает, спасибо!!!
Точнее даже вот так:
func addJoeyTo(inout persons:[Person]) { // не inout var, а просто var
    persons.append(Person(name: "Joey", age: 25))
}
...
addJoeyTo( &programmers ) // нужно использовать &
Спасибо за комментарий! Но в вашем примере вычисляемый class var, а не хранимый. Именно поэтому приходится выносить инициализацию во внешний scope. ;) Этот подход тоже используется — правда, он не lazily loaded.
Да, действительно, я хреново сформулировал, на самом деле закрепляются в строгих ссылках вообще все закепчеренные блоком обьекты классов.
Спасибо за замечание!!!

Спасибо за подсказку!!!
Да, на всякий случай обертку dispatch нужно перенести непосредственно в код колбека.

Information

Rating
Does not participate
Registered
Activity