简介

今天的主角是Reactive Cocoa,聊聊Reactive Cocoa的常见使用:KVO、Target、Delegate、Notification。

Reactive Cocoa 是一个重量级框架,非常的牛,为什么说Reactive Cocoa非常的牛?
我们所熟知的iOS 开发中的事件包括:

  • Target
  • Delegate
  • KVO
  • 通知
  • 时钟
  • 网络异步回调

ReactiveCocoa ,就是用信号接管了iOS 中的所有事件;也就意味着,用一种统一的方式来处理iOS中的所有事件,解决了各种分散的事件处理方式,显然这么一个庞大的框架学习起来也会比较难!而且如果习惯了iOS原生的编程,可能会觉得不习惯!

先看一个图:

从这张图中,可以看出利用信号,ReactiveCocoa接管iOS 的所有事件,抛给开发者对事件作出三个相应反应;

可以用一张图来简要说明

RAC 的特点

  • 通过 block 函数式 + 链式 的编程,可以让所有相关的代码继承在一起!
    函数式 && 链式?
  • 使用时需要注意循环引用,@weakify(self) / @strongify(self) 组合解除循环引用;?

下面用iOS开发中常见的五种事件来说明ReactiveCocoa的常见用法!

下载框架:

  • 新建iOS工程
  • 进入终端,建立 Podfile,并且输入以下内容
  • # Uncomment this line to define a global platform for your project
    platform :ios, '8.0'
    # Uncomment this line if you're using Swift
    use_frameworks!
    pod 'ReactiveCocoa', '~> 4.0.4-alpha-4'
  • 版本说明:
  •  2.5 纯 OC
    3.0 正式版支持 Swift 1.2
    4.0 测试版支持 Swift 2.0

在终端输入以下命令安装框架
$ pod install

KVO 监听

程序实现: 监控Person name的属性变化;在touchesBegan中改变name的值,并将变化体现在UILabel上,实现KVO的监控功能;

  • 注意,RAC 的信号一旦注册不会主动释放
  • 只要在 block 中包含有 self. 一定会出现强引用* 需要使用 @weakify(self) / @strongify(self) 组合使用解除强引用

//person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@end

 

// ViewController.m
#import "ViewController.h"
@import ReactiveCocoa;
#import "Person.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (nonatomic, strong) Person *person; @end
@implementation ViewController
- (Person *)person
{
if (!_person)
{
_person = [[Person alloc] init]; } return _person;
}//实现person的懒加载
- (void)viewDidLoad
{
[super viewDidLoad];
[self demoKvo];
}// 在viewDidLoad中调用demoKvo方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
self.person.name = [NSString stringWithFormat:@"zhang %d",arc4random_uniform(100)];
}//在touchesBegan方法中改变person的name属性。

 

/**
* 1、为了测试此函数,增加了一个Person类 && 一个Label;点击屏幕则会等改Lable的值
*/
#pragma -mark KVO 监听

-(void)demoKvo{
  @weakify(self)
  [RACObser(self.person,name)
  subscribeNext:^(id x){
  @strongify(self)
  self.nameLabel.text = x ;
  }
  ];
}
@end

文本框输入事件监听

#pragma -mark 文本框输入事件监听
/**
* 2、为了测试此函数,增加了一个nameText;监听文本框的输入内容,并设置为self.person.name
*/
-(void)demoTextField{
@weakify(self);
[[self.nameText rac_textSignal]
 subscribeNext:^(id x){
  @stongify(self);
  NSLog(@"%@",x);
  self.person.name = x ;
  }
  ];
}

文本框组合信号

#pragma -mark 文本信号组合
/**
* 3、为了验证此函数,增加了一个passwordText和一个Button,监测nameText和passwordText
* 根据状态是否enabled
*/
-(void)textFileCobination{
id signals = @[[self.nameText rac_textSigal],[self.passWordText rac_textSignal]];//包装两个信号数组
@weakify(self);
[[RACSignal
  combineLatest:signals]//组合最新的信号
  subscribeNext:^(RACTuple *x){//响应者 参数数组
  
  @strongify(self);
  NSString *name = [x first];  //将数组第一个赋值给name
  NSString *password = [x second];  //将数组第二个赋值给password
  
  if(name.length > 0 && password.length > 0){
  self.loginButton.enabled = YES;
  self.person.name = name;
  self.person.password = password;
}  else{
self.loginButton.enabled = NO;
}
}];
}

按钮监听

#pragma   -mark 按钮监听

/**
* 4、验证此函数:当loginButton可以点击时,点击button输出person的属性,实现监控的效果
*/
- (void)buttonDemo{
  
  @weakify(self);   [[self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside]
  
  subscribeNext:^(id x){
  @strongify(self);
  NSLog(@"person.name: %@  person.password: %@",self.person.name,self.person.password);
}
];
}

代理方法

#pragma -mark 代理方法
/**
* 5、验证此函:nameText的输入字符时,输入回撤或者点击键盘的回车键使passWordText变为第一响应者(即输入光标移动到passWordText处)
*/
-(void)delegateDemo{ @weakify(self)
//1.定义代理
self.proxy = [[RACDelegateProxy alloc]  initWithProtocol:@protocol(UITextFieldDelegate)]; //2.代理去注册文本框的监听方法 [self.proxy  rac_signalForSelector:@selector(textFieldShouldReturn:)]
subscribeNext:^(id x){
@strongify(self)
if(self.nameText.hasText){
  [self.passWordText becomeFirstResponder];  
}
}];
self.nameText.delegate = (id<UITextFieldDelegate>)self.proxy;
}

通知

#pragma -mark 通知
/**
* 验证此函数:点击textFile时,系统键盘会发送通知,打印出通知的内容
*/
- (void)notificationDemo {
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillChangeFrameNotification object:nil]
subscribeNext:^(id x) {
NSLog(@"notificationDemo : %@", x);
}
];
}


 

[HMLY]9.深入浅出-iOS Reactive Cocoa的常见用法的更多相关文章

  1. iOS-Reactive Cocoa的常见用法

    今天是周末,临近年底,工作上遇到不可抗力,会有点一些变动!这多少会让人有一点静不下来,但需克制,Reactive Cocoa是今天的主角! 废话不多说,今天聊聊Reactive Cocoa的常见使用! ...

  2. iOS开发之OC篇-响应式编程Reactive Cocoa

    一.Reactive Cocoa 介绍 Reactive Cocoa 是 iOS 开发的一个 "重量级" 框架 高大上的概念:响应式编程 核心概念:信号 Signal 官方网站:h ...

  3. RAC(Reactive Cocoa)常见的类

    导入ReactiveCocoa框架 在终端,进入Reactive Cocoa文件下 创建podfile 打开该文件 并配置 use_frameworks! pod 'ReactiveCocoa', ' ...

  4. 深入浅出--iOS的TCP/IP协议族剖析&&Socket

    深入浅出--iOS的TCP/IP协议族剖析&&Socket   简介 该篇文章主要回顾--TCP/IP协议族中的TCP/UDP.HTTP:还有Socket.(--该文很干,酝酿了许久! ...

  5. iOS 开发多线程篇—GCD的常见用法

    iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...

  6. iOS开发UI篇—常见的项目文件介绍

    iOS开发UI篇—常见的项目文件介绍 一.项目文件结构示意图 二.文件介绍 1.products文件夹:主要用于mac电脑开发的可执行文件,ios开发用不到这个文件 2.frameworks文件夹主要 ...

  7. iOS开发多线程篇—GCD的常见用法

    iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...

  8. (转)深入浅出 iOS 之生命周期

    原文:http://www.cocoachina.com/applenews/devnews/2011/0817/3129.html 深入浅出 iOS 之生命周期 发布于:2011-08-17 10: ...

  9. 【转】深入浅出 iOS 之生命周期

    [iOS]深入浅出 iOS 之生命周期 深入浅出 iOS 之生命周期  http://blog.csdn.net/kesalin/article/details/6691766 罗朝辉(http:// ...

随机推荐

  1. return 使用和闭包

    1.return 使用 案例一: var a=1; for(var b=0; b<10; b++){ return b; }; sonsole.log(b)//返回为空 个人认为此处左右与为全局 ...

  2. every、some、filter、map、forEach 方法的区别总结

    API功能描述: [every]:Boolean 遍历数组并执行回调,如果每个数组元素都能通过回调函数的测试则返回true,否则返回false.一旦返回false,将立即终止循环. [some]:Bo ...

  3. POI操作EXCEL之导出Excel(设置有效性,下拉列表引用)

    本人使用的是poi-bin-3.10-FINAL-20140208.zip 版本的poi以下是程序关键代码: //需要引用的类 import java.io.File; import java.io. ...

  4. Weblogic Server 的下载,安装配置与部署

    下载 下载页面: http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-for-dev-1703574.html 目前 ...

  5. Binder机制,从Java到C (10. Binder驱动)

    Binder驱动的代码都在kernel里面,这里就简单讲一下里面涉及到的几个东西: 1.MemoryBinder其实本质上就是一中数据传输方式,这种方式是通过binder driver实现的. 我们知 ...

  6. Unity Container

    Unity Container中的几种注册方式与示例 2013-12-08 22:43 by 小白哥哥, 22 阅读, 0 评论, 收藏, 编辑 1.实例注册 最简单的注册方式就是实例注册,Unity ...

  7. 【IOS开发】《多线程编程指南》笔记

    线程是单个应用中可以并发执行多个代码路径的多种技术之一.虽然更新的技术如操作对象(Operation)和Grand Central Dispatch(GCD),提供一个等价现代化和高效的基础设施来实现 ...

  8. [Usaco2008 Open]Roads Around The Farm分岔路口[水题]

    Description     约翰的N(1≤N≤1,000,000,000)只奶牛要出发去探索牧场四周的土地.她们将沿着一条路走,一直走到三岔路口(可以认为所有的路口都是这样的).这时候,这一群奶牛 ...

  9. 如何在大型的并且有表分区的数据库中进行DBCC CHECKDB操作

    如何在大型的并且有表分区的数据库中进行DBCC CHECKDB操作 其实这个问题已经在<SQLSERVER企业级平台管理实践>里徐老师已经讲过了,不过我想用自己的语言再讲详细一些 笔记链接 ...

  10. (翻译) Android Accounts Api使用指南

    本文翻译自Udinic的文章Write your own Android Authenticator,可能需要FQ才能阅读.这是译者目前能找到的介绍如何使用Android的Accounts Api最好 ...