函数响应式编程(FRP)框架--ReactiveCocoa

        身为RAC的小白,希望可以和大家讨论一下关于ReactiveCocoa,这个采用函数响应式编程(FRP)的框架,以下会对ReactiveCocoa简称为RAC。

        之前看过一遍文章,说的是作为一个iOS开发者,写的每一行代码几乎都是在相应某个事件,例如按钮的点击,收到网络消息,属性的变化(通过KVO)或者用户位置的变化(通过CoreLocation)。但是这些事件都用不同的方式来处理,比如action、delegate、KVO、callback等。我很赞同这种说法,于是,即然这样的话,那我们为什么不把这些需要响应的事件流统一放在一起呢。很幸运的是,Github有一个开源项目,即ReactiveCocoa简称RAC,就是基于响应式编程思想的Objective-C实践。

          那么何为RAC呢?

         RAC是为应用中发生的不同事件流提供了一个标准接口,我们可以使用一些基本工具来更容易的连接、过滤和组合。


RAC结合了几种编程风格:

       函数式编程(Functional Programming):使用高阶函数,例如函数用其他函数作为参数。

       那么什么是函数式编程呢? 

        简单的一句话说,『尽量将操作都写在一起,也就是写成一个嵌套的函数』这就是函数式编程的核心思想,代表性项目 AFN

而它的本质就是,往方法里面传入block , 方法里面在嵌套block.

          响应式编程(Reactive Programming):关注于数据流和变化传播。

          其实大家都接触过响应式编程,就是所谓的KVO。

          KVO 大家肯定都接触过吧?一个属性的改变立刻做出反应,我不管你的属性有没有值,我不管你的属性来了没有,我就是监听,只要你一来我就做出响应,其实KVO的本质就是,监听一个对象,他有没有监听set方法。然后将set方法重写。RAC 就是典型的响应式编程,我信号发出去之后订阅者就是负责监听,不管你来不来,不管你有没有,反正我就是监听着,只要你一来我就做出反应。

         所以,你可能听说过ReactiveCocoa被描述为函数响应式编程(FRP)框架。

        有句比喻很好很形象的对RAC做了总结:“可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多个水龙头合并成一个新的水龙头(combineLatest:reduce:),这样只要其中的一个水龙头有玻璃球出来,这个新合并的水龙头就会得到这个球。”--  来自博文http://blog.csdn.net/xdrt81y/article/details/30624469

首先导入RAC框架:

可以通过CocoaPods导入RAC框架:(注意RAC的版本)

导入  pod 'ReactiveCocoa', '~> 2.4.0'  &&  use_frameworks! #导入才不会报错 

或者  导入pod 'ReactiveObjC', '~> 3.0.0'

        ReactiveCocoa 2.5以后引入Swift,所以我们在OC开发中需要配入之前的版本,否则会错的一发不可收拾哦!!!!!

        RAC为应用中发生的不同事件流提供了一个标准接口。在ReactiveCocoa术语中这个叫做信号(signal),由RACSignal类表示。

        ReactiveCocoa signal(RACSignal)发送事件流给它的subscriber(订阅者)。目前总共有三种类型的事件:next、error、completed。一个signal在因error终止或者完成前,可以发送任意数量的next事件。RACSignal有很多方法可以来订阅不同的事件类型。每个方法都需要至少一个block,当事件发生时就会执行block中的逻辑。


那么下面来一下实战操作吧!!!!!


一、创建信号

        使用RACSignal的createSignal:方法来创建信号。方法的参数是一个block,这个block描述了这个信号。当这个信号有subscriber时,block里的代码就会执行。

       block的参数是一个subscriber实例,它遵循RACSubscriber协议,协议里有一些方法来产生事件,你可以发送任意数量的next事件,或者用error\complete事件来终止。本例中,信号发送了一个next事件来表示登录是否成功,随后是一个complete事件。

      这个block的返回值是一个RACDisposable对象,它允许你在一个订阅被取消时执行一些清理工作。当前的信号不需要执行清理操作,所以返回nil就可以了。

        - (RACSignal*)signInSignal {

               return[RACSignalcreateSignal:^RACDisposable*(idsubscriber){

      [self.signInService   signInWithUsername:self.usernameTextField.text password:self.passwordTextField.text

complete:^(BOOLsuccess){

         [subscribersendNext:@(success)];

          [subscribersendCompleted];

         }];

         returnnil;

     }];

}

二、使用RAC宏

       RAC宏允许直接把信号的输出应用到对象的属性上。RAC宏有两个参数,第一个是需要设置属性值的对象,第二个是属性名。每次信号产生一个next事件,传递过来的值都会应用到该属性上。

        RAC(self.passwordTextField.backgroundColor) = [validPassword Signalmap:^id(NSNumber*passwordValid) {

                NSLog(@"%d",[passwordValidboolValue]);

       return[passwordValid boolValue]?[UIColor clearColor]:[UIColor yellowColor];

       }];

       RAC(self.usernameTextField.backgroundColor) = [validUsername Signalmap:^id(NSNumber*usernameValid) {

                  NSLog(@"%d",[usernameValid boolValue]);

       return[usernameValid boolValue]?[UIColor clearColor]:[UIColor yellowColor];

     }];


三、信号聚合

       使用combineLatest:reduce:方法把几个信号RACSignal产生的最新的值聚合在一起,并生成一个新的信号。每次这两个源信号的任何一个产生新值时,reduce block都会执行,block的返回值会发给下一个信号。

            RACSignal *signUpActiveSignal = [RACSignalcombineLatest:@[validUsernameSignal,validPasswordSignal]        reduce:^id(NSNumber*usernameValid,NSNumber*passwordValid){

             return@([usernameValidboolValue]&&[passwordValid boolValue]);

            }];

            [signUpActiveSignal subscribeNext:^(NSNumber*signupActive) {

            self.signInButton.enabled= [signupActive boolValue];

}];


ReactiveCocoa的核心就是信号,而它不过就是事件流,ReactiveCocoa的主旨是让你的代码更简洁易懂!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容