RACSignal
Фреймворк основан на сигналах. Сигнал — это объект, в котором хранится ссылка на наблюдаемый объект и ссылки на подписчиков. Когда сигнал видит, что наблюдаемый объект изменился, он пересылает новое значение подписчикам. Подписчиком может быть другой сигнал, блок, а также любой объект.
Пример 1. Сигнал, наблюдающий свойство name и передающий значения в блок:
User *user = [User new]; RACSignal *userNameSignal = RACObserve(user, name); [userNameSignal subscribeNext:^(NSString *newValue) { NSLog(@"New value: %@", newValue); }]; user.name = @"ivan"; //Вывод в консоли: //New value: ivan
Преобразование сигналов
До того, как новое значение объекта дойдет до подписчика, оно может быть подвергнуто различным преобразованиям. Такими как:
- изменение значения (map)
- фильтрация (filter, ignore)
- объединение с другим значением (combine)
- упрощение нескольких сигналов в одно (reduce)
Пример 2. Продолжая первый пример, изменим передаваемое значение:
User *user = [User new]; RACSignal *userNameSignal = RACObserve(user, name); [[userNameSignal map:^id(NSString *newValue) { return newValue.capitalizedString; }] subscribeNext:^(NSString *newValue) { NSLog(@"New value: %@", newValue); }]; user.name = @"ivan"; //Теперь все значения будут передаваться подписчикам с большой буквы. //Вывод в консоли: //New value: Ivan
Биндинги
Преобразования не были бы так полезны, если бы не биндинги. Они позволяют создать зависимость одного свойства от другого:
- Кнопка авторизации активна только если введены логин и пароль
- Поля ввода логина и пароля отключены, когда происходит авторизация
- Свойство user.isValidName меняется автоматически когда меняется свойство user.name.
«Прибинженные» поля меняются сами, поэтому не надо в коде следить за актуальными значениями. Это полезно, например, в приложениях со сложной логикой интерфейса.
Продолжая предыдущий пример, сделаем биндинг для свойства user.login, чтобы подходящий логин автоматически предлагался пользователю на основе имени:
RAC(user, login) = [userNameSignal map:^id(NSString *name) { return [name stringByReplacingOccurrencesOfString:@" " withString:@"_"].lowercaseString; }]; user.name = @"Vladimir Petrov"; NSLog(@"Login: %@", user.login); // Вывод в консоли: // Login: vladimir_petrov
Минусы
Начав использовать ReactiveCocoa, уже трудно представить разработку без него. Но у этого фреймворка есть минусы, которые для кого-то могут быть существенными:
- Частое использование KVO может снизить производительность. Решается оптимизацией и неиспользованием RAC’a в высоконагруженных участках кода.
- Сложная отладка из-за частого использования блоков, особенно внутри самого ReactiveCocoa. Порой в поиске ошибки помогает лишь интуитивное понимание objective-c.
- Легко допустить ошибку и они приводят к неожиданным последствиям.
- Перегруженный синтаксис. Этой проблемы не будет с переходом на swift.
В заключение
Описанное выше — лишь малая часть того, что может ReactiveCocoa. Однако, даже применив только это, можно заметно упростить свою работу. Если эта статья будет кому-нибудь интересна, в следующей можно будет разобрать более сложные и интересные части этого фреймворка.
ссылка на оригинал статьи http://habrahabr.ru/post/248771/
Добавить комментарий