Pull to refresh

Comments 14

В начале видео я чуть чуть расстроился что стали показывать 2 одинаковых экрана, чуть позже пришлось расстроиться что стали показывать 0 экранов. После пятой минуты оператор исправился. На 8й минуте опять испортился. Несмотря на миксер внутри оператора, спасибо за видео, интересно.
Оператор, очень «не хороший» человек :(
У автора в коде есть явная проблема.

[self.viewModel.updateContentSignal subscribeNext: ^(id x){
   [self.collectionView reloadData];
]


В этом коде создается циклическая ссылка на self. В этом случае нужно либо использовать @weakify/@strongify из libextobjc/EXTScope (кажется входит в RAC) но я предпочитаю liftSelector

[self rac_liftSelector:@selector(updateCollectionView:) withSignals:self.viewModel.updateContentSignal, nil];

...

- (void)updateCollectionView:(id)sender {
   [self.collectionView reloadData];
}


Вообще, вопреки тому что subscribeNext: используется в каждом примере, его лучше вообще нигде не использовать, очень грязная практика.
Использовать rac_liftSelector:withSignals: для сайд-эффектов — тоже спорная практика (хотя и сам грешу).

И в защиту subscribeNext: скажу, что для новичков такие примеры явно понятнее, чем какая-то макро-магия RAC/RACObserve.

Ну и если подумать на перспективу, то в Swift, пожалуй, стоит использовать только явную подписку, иначе будет всякий ужас вроде строковых селекторов или key path'ов, это намного хуже, особенно в Swift.
хм. Замечание верное, спасибо за ссылку. Однако, тут можно поспорить по поводу сайд-эффектности -reloadData в этом случае. Можно интерпретировать эту ситуацию как reloadData — событие состоящее в отношении с updateContentSignal.
Мне просто очень не нравится @weakify/@strongify. Слишком легко его забыть и сделать багу (вот как спикер например, он же упомянул эти штуки в докладе, но написать забыл)

Пользуясь случаем попиарюсь. Чтобы победить stateful UITableView в свое время написал такую приблуду github.com/gavrix/TableViewReactiveAdapter которая как раз могла бы скрыть состояния и сайд-эффекты в рассматриваемом примере (конечно требуется адаптация для CollectionView)
Оператор — очень плохой человек. Вроде бы очень интересно посмотреть, но не возможно ибо оператору почему-то ну очень нравится спикер. Зачем снимать спикера крупным планом? Его можно вообще не снимать!
Если я правильно понял комментарий, вам хочется посмотреть на pdf.
Интересно.
Насчёт навигации.
В .NET'овском MVVM мире мы навигируемся между вьюмоделями, то есть формируются данные для вьюмодели следующего экрана, и мы «показываем» ее.
Я понимаю, что отличие больше идеологическое, но ключевое в нем — слабая связь между View и ViewModel. View знает, какую ViewModel она отображает. Но таких вьюх может быть несколько (для iPhone и iPad, к примеру) и слой представления (в вашем случае, видимо, Router) сам решает, какую сейчас отобразить.
Я не согласен с автором доклада. ViewModel не дожна знать о каких то переходах. Использование Router вполне имеет место но не внутри ViewModel. Например автор делает так

@implementation SectionViewModel

— (void)mobileBtnPressed {
[self.router showMobileTalks];
}

end

Внедрение знания о навигации во ViewModel я считаю фундаментально ошибкой автора в использовании MVVM.
Этот код [self.router showMobileTalks]; должен вызвывать ViewController, так как это относится уровню представления в MVVM — покзать это модально или в дочернем контейнере или еще как то.

(PS) не пойму почему не работают теги у меня в комментариях…
Переходы, сами по себе — бизнес-логика. Только БЛ знает, что с твита надо перейти на его профиль. так что переходы во ViewModel — нормально.
Но вы правы в том, что ViewModel не должна ничего знать о модальности, вложенности и т.д. Это уровень представления. Идеально — ViewModel просто просит представление отобразить другую вьюмодель, а представление само разбирается как это сделать. Но Логику переходов не знает.
Например storyboard? VC только просит вызвать переход и не знает что там дальше произойдет
Относительно использования ViewModelей в табличке, вместо тоо, чтобы писать так:
RAC(self.titleLabel, text) = RACObserve(self.viewModel, someValue)

и отписываться каждый раз при prepareForReuse,

Можно использовать следующую запись (обращаем внимание на запятые ;)
RAC(self.titleLabel, text) = RACObserve(self, viewModel.someValue)
Sign up to leave a comment.