对于一个应用来说,绝大部分的时间都是在等待某些事件的发生或响应某些状态的变化,比如用户的触摸事件、应用进入后台、网络请求成功刷新界面等等,而维护这些状态的变化,常常会使代码变得非常复杂,难以扩展。而 ReactiveCocoa 给出了一种非常好的解决方案,它使用信号来代表这些异步事件,提供了一种统一的方式来处理所有异步的行为,包括代理方法、block 回调、target-action 机制、通知、KVO 等:

// 代理方法
[[self
rac_signalForSelector:@selector(webViewDidStartLoad:)
fromProtocol:@protocol(UIWebViewDelegate)]
subscribeNext:^(id x) {
// 实现 webViewDidStartLoad: 代理方法
}]; // target-action
[[self.avatarButton
rac_signalForControlEvents:UIControlEventTouchUpInside]
subscribeNext:^(UIButton *avatarButton) {
// avatarButton 被点击了
}]; // 通知
[[[NSNotificationCenter defaultCenter]
rac_addObserverForName:kReachabilityChangedNotification object:nil]
subscribeNext:^(NSNotification *notification) {
// 收到 kReachabilityChangedNotification 通知
}]; // KVO
[RACObserve(self, username) subscribeNext:^(NSString *username) {
// 用户名发生了变化
}];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

1.监听UITextField数值 赋值ViewModel

RAC(self.loginVM, username) = _textFieldAccount.rac_textSignal;
  • 1

2.监听ViewModel数值 赋值UILabel

RAC(self.labelRoundNumber, text) = RACObserve(self.homePageVM, waitNum);
  • 1

问题:RAC 和RACOberve的区别?RAC(tagartA,keypathA)是对对象tagartA的keypathA属性进行赋值,RACObserve(tagartB,keypathB)是监听tagartB的keypathB属性的值;

3.监听UITextView控件 text属性

@weakify(self);
[self.textViewAdvice.rac_textSignal subscribeNext:^(NSString *content){
@strongify(self);
self.textFieldPlaceholder.hidden = (content && content.length > 0);
}];
  • 1
  • 2
  • 3
  • 4
  • 5

4.监听UIButton控件 UIControlEventTouchUpInside事件

@weakify(self)
[[self.buttonLogin
rac_signalForControlEvents:UIControlEventTouchUpInside]
subscribeNext:^(id x) {
@strongify(self)
[MBProgressHUD showHUDAddedTo:self.view
animated:NO];
[self.loginVM sendLogin];
}];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.自定义RACSubject消息

@property (nonatomic, strong, readwrite) RACSubject *successLogin;
@property (nonatomic, strong, readwrite) RACSubject *failureLogin; - (void)initialize {
_successLogin = [RACSubject subject];
_failureLogin = [RACSubject subject];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6.消息RACSubject传递

- (void)sendLogin {
NSDictionary *dictParams = @{
@"UserName":self.username,
@"PassWord":self.password
};
@weakify(self);
[WebServiceManager requestLoginWithParams:dictParams
andBlock: ^(id data, id error) {
@strongify(self);
if (error) {
return;
}
if ([data isMemberOfClass:[UserModel class]]) {
[self.successLogin sendNext:userModel];
}
else {
[self.failureLogin sendNext:(NSString *)data];
}
}];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

7.消息RACSubject接收

@weakify(self)
[self.loginVM.successLogin subscribeNext:^(UserModel *userModel) {
@strongify(self);
[UserModel userModel:userModel];
[HomePageVC rootViewController];
[MBProgressHUD hideHUDForView:self.view
animated:YES];
}]; [self.loginVM.failureLogin subscribeNext:^(NSString *data) {
@strongify(self);
self.textFieldAccount.text = @"";
self.textFieldPassword.text = @"";
kMRCError(data);
[MBProgressHUD hideHUDForView:self.view
animated:YES];
}];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

8.监听键盘通知

[[[NSNotificationCenter defaultCenter]
rac_addObserverForName:UIKeyboardWillShowNotification
object:nil]
subscribeNext:^(NSNotification *notification) {
NSDictionary *info = [notification userInfo];
NSValue *keyboardFrameValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
CGFloat height_temp = 195 - (kViewHeight(self.view) - keyboardFrame.size.height - 90) / 2;
[_scrollViewMaster setContentOffset:CGPointMake(0, height_temp)
animated:YES];
}
]; [[[NSNotificationCenter defaultCenter]
rac_addObserverForName:UIKeyboardWillHideNotification
object:nil]
subscribeNext:^(NSNotification *notification) {
[_scrollViewMaster setContentOffset:CGPointMake(0, 0)
animated:YES];
}
]; [[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

MVVM+RAC

MVVM在功能上其实是Model+View(view、ViewController)+ViewModel,所以与之前不同的地方就是每个ViewController都会有一个与之对应的ViewModel,它处理业务逻辑和网络请求,从而降低ViewController的臃肿。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DevanChen/article/details/50993663

ReactiveCocoa使用记录-网络登录事件的更多相关文章

  1. iOS开发之记录用户登录状态

    iOS开发之记录用户登录状态 我们知道:CoreData的配置和使用步骤还是挺复杂的.但熟悉CoreData的使用流程后,CoreData还是蛮好用的.今天要说的是如何记录我们用户的登陆状态.例如微信 ...

  2. Oracle 中记录用户登录信息

    我们可以使用 Oracle Audit 函数来记录用户登录信息,但是如果开放了 Audit 函数将会使 Oracle 性能下降,甚至导致 Oracle 崩溃.那我们如何才能记录用户登录信息呢?其实我们 ...

  3. net mvc中实现记录用户登录信息(记住登录效果)

    现记录用户登录信息(记住登录效果) 本文讲述了使用cookies实现网站记住登录效果,效果如下: 主要实现方法,当用户选择记住登录时建立cookies保存用户名和用户密码,当用户登录不选择记住登录时, ...

  4. loadrunner录制时,设置能不记录所有的事件

    loadrunner录制时,设置能不记录所有的事件 可以做如下两点设置: 1. 在record option下的recording选项卡下选择html advance,在script type下选择A ...

  5. Windows 10家庭版也能共享打印机(中)解除Guest账户网络登录限制,实现局域网共享

    由于Windows系统默认是禁止Guest账户从网络登录的.我们须要解除这个限制.首先想到的是用组策略编辑器gpedit.msc. 可是Windows 10家庭版没有组策略编辑器,我们先尝试用U盘把W ...

  6. JavaScript 回车键绑定登录 事件 常用键位码(keyCode)

    1.回车键绑定登录事件 $(document).keydown(function (e) { if ((e.keyCode || e.which) == 13) { //document.queryS ...

  7. [记录] Linux登录前后提示语

    Linux登录前后提示语 /etc/issue 本地(虚拟控制台KVM等)登录前提示语,支持转义字符 /etc/issue.net 远程(telnet,ssh)登录前提示语,不支持转义字符 /etc/ ...

  8. spring security实现记录用户登录时间等信息

    目录 spring security实现记录用户登录时间等信息 一.原理分析 二.实现方式 2.1 自定义AuthenticationSuccessHandler实现类 2.2 在spring-sec ...

  9. Windows Server查看和记录远程登录信息的方法

    前两天我的一台Windows Server 2012R2的服务器中了传说中的cryptowall病毒,所有数据文件都被加密,需要我支付1个比特币才能解码.幸好服务器上没什么重要的文件,还好我没钱,我选 ...

随机推荐

  1. ES 遇到 unassigned shard如何处理?

    解决方法:(1)如果是红色的,可以直接分片shard给你认为有最新(或最多)数据的节点.见下: 摘自:https://discuss.elastic.co/t/how-to-resolve-the-u ...

  2. angular4(3)angular脚手架引入scss

    scss..sass....sccc...ssss...ccccc......MMP················· 先说下scss和sass的异同: SCSS 是 Sass 3 引入新的语法,其语 ...

  3. Swift学习笔记(6):控制流

    目录: For-In While If-Else, Guard-Else Switch 控制转移 For-In 可以使用for-in语句循环遍历集合.区间.元组.字符串. // 遍历区间,返回元素值 ...

  4. python 3.x 学习笔记12 (反射 and 异常)

    1.反射通过字符串映射或修改程序运行时的状态.属性.方法 getattr(obj,name_str):  根据字符串name_str去获取obj对象里的对应的方法的内存地址 hasttr(obj,na ...

  5. .NET深入解析LINQ框架2

    1].开篇介绍 在开始看本篇文章之前先允许我打断一下各位的兴致.其实这篇文章本来是没有打算加“开篇介绍”这一小节的,后来想想还是有必要反馈一下读者的意见.经过前三篇文章的详细讲解,我们基本上对LINQ ...

  6. PIC18F26K20

    Clock Four Crystal modes, Two External clock modes,  Two RC Oscillator, Internal oscillator, PLL

  7. pthread 的 api 分类

    pthreads defines a set of C programming language types, functions and constants. It is implemented w ...

  8. How Javascript works (Javascript工作原理) (三) 内存管理及如何处理 4 类常见的内存泄漏问题

    个人总结: 1.两种垃圾回收机制: 1)引用标记算法:如果检测到一个对象没有被引用了,就清除它. ***这种算法不能处理循环引用的情况*** 2)标记—清除算法:从根(全局变量)开始向后代变量检测,任 ...

  9. codeforces 914 D Bash and a Tough Math Puzzle

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #i ...

  10. iptables 配置端口及转发

    iptables端口转发指令:iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443 iptables配 ...