对于一个应用来说,绝大部分的时间都是在等待某些事件的发生或响应某些状态的变化,比如用户的触摸事件、应用进入后台、网络请求成功刷新界面等等,而维护这些状态的变化,常常会使代码变得非常复杂,难以扩展。而 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. NOIP2017提高组模拟赛 7(总结)

    NOIP2017提高组模拟赛 7(总结) 第一题 斯诺克 考虑这样一个斯诺克球台,它只有四个袋口,分别在四个角上(如下图所示).我们把所有桌子边界上的整数点作为击球点(除了4个袋口),在每个击球点我们 ...

  2. bzoj1293: [SCOI2009]生日礼物(stl堆)

    1293: [SCOI2009]生日礼物 题目:传送门 题解: 据说这道题乱搞随便就水过了 本蒟蒻想到了一个用堆的水法(还专门学了学queue): 如果把每一种颜色的下一个位置都记录一下的话,一开始就 ...

  3. WebStorm配置github

    1.配置github 2.安装git,配置git 3.配置ssh,用git中的git Bash 4.迁出项目 5.提交文件 6.查看

  4. (二)Ribbon(负载均衡的客户端)+Rest

    前面讲了服务的注册与发现,微服务项目会把项目的各个业务需求划分成几个模块来单独提供服务,各服务间的调用都是采用Http Restful来实现,但是在SpringClound中服务间的调用有两种方式:一 ...

  5. fatal error C1003: error count exceeds number; stopping compilation解决方法

    [error]C1003: error count exceeds 100; stopping compilation ...winnt.h 在项目工程中添加#include<windows.h ...

  6. js邮箱,汉字,数字 表单验证

    //电子邮箱验证 function isEmail(str) { var myreg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_ ...

  7. css part 2

    CSS 盒子模型 margin:            用于控制元素与元素之间的距离:margin的最基本用途就是控制元素周围空间的间隔,从视觉角度上达到相互隔开的目的. padding:       ...

  8. URL正则

    现有需求 表单填写域名只能填写 baseURL 或者 baseURL+端口 不带协议 否则为不合法 String url1 = ".com:90"; String url2 = & ...

  9. ajax请求携带 cookie

    之前都有这样一个理解:ajax请求时是不会自动带上cookie的,要是想让他带上的话,必须哟啊设置withCredential为true.这个说法会让人产生完全扭曲的误解,我就是其中之一.完整的无歧义 ...

  10. 异步调用task

    异步主要用来提升程序性能,会增加系统的开销(新建一个线程去执行异步任务). 可应用于耗时长的操作,比如:访问数据库时(应用程序和数据库不在同一台服务器上).服务之间的调用(服务会分散在不同的服务器上) ...