ReactiveCocoa


1.ReactiveCocoa簡介

ReactiveCocoa(簡稱為RAC),是由Github開源的一個應(yīng)用于iOS和OS開發(fā)的新框架,Cocoa是蘋果整套框架的簡稱,因此很多蘋果框架喜歡以Cocoa結(jié)尾骗卜。

2.ReactiveCocoa作用

在我們iOS開發(fā)過程中,經(jīng)常會響應(yīng)某些事件來處理某些業(yè)務(wù)邏輯闲坎,例如按鈕的點擊旺垒,上下拉刷新寨躁,網(wǎng)絡(luò)請求宛裕,屬性的變化(通過KVO)或者用戶位置的變化(通過CoreLocation)瑟啃。但是這些事件都用不同的方式來處理,比如action揩尸、delegate蛹屿、KVO、callback等疲酌。

其實這些事件蜡峰,都可以通過RAC處理,ReactiveCocoa為事件提供了很多處理方法朗恳,而且利用RAC處理事件很方便湿颅,可以把要處理的事情,和監(jiān)聽的事情的代碼放在一起粥诫,這樣非常方便我們管理油航,就不需要跳到對應(yīng)的方法里。非常符合我們開發(fā)中高聚合怀浆,低耦合的思想谊囚。

3.編程思想

在開發(fā)中我們也不能太依賴于某個框架,否則這個框架不更新了执赡,導致項目后期沒辦法維護镰踏,比如之前Facebook提供的Three20框架,在當時也是神器沙合,但是后來不更新了奠伪,也就沒什么人用了。因此我感覺學習一個框架首懈,還是有必要了解它的編程思想绊率。

先簡單介紹下目前咱們已知的編程思想。

3.1 面向過程:處理事情以過程為核心究履,一步一步的實現(xiàn)滤否。

3.2 面向?qū)ο螅喝f物皆對象

3.3 鏈式編程思想:是將多個操作(多行代碼)通過點號(.)鏈接在一起成為一句代碼,使代碼可讀性好。a(1).b(2).c(3)

  • 鏈式編程特點:方法的返回值是block,block必須有返回值(本身對象)最仑,block參數(shù)(需要操作的值)

  • 代表:masonry框架藐俺。

  • 練習一:模仿masonry,寫一個加法計算器盯仪,練習鏈式編程思想紊搪。

//
//  ViewController.m
//  01-鏈式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import "ViewController.h"
#import "NSObject+Calculate.h"
#import "CalculateManager.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    int result =  [NSObject kx_makeCalculate:^(CalculateManager * manager) {
      
//      manager.add(5)
//      [[manager add:5] add:5];
        //用block替代方法
        //把怎么計算的代碼封裝到block中

        manager.add(5).add(10);
        
    }];
    NSLog(@"%d",result);
}

@end


#pragma mark ------NSObject+Calculate.h文件

//  NSObject+Calculate.h
//  01-鏈式編程思想
//
//  Created by 徐流洋 on 2017/5/18.
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import <Foundation/Foundation.h>

@class CalculateManager;

@interface NSObject (Calculate)

+ (int )kx_makeCalculate:(void(^)(CalculateManager *manager))block;

@end
#pragma mark -----------------------------------------------

#pragma mark --------NSObject+Calculate.m
//  NSObject+Calculate.m
//  01-鏈式編程思想
//
//  Created by 徐流洋 on 2017/5/18.
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import "NSObject+Calculate.h"
#import "CalculateManager.h"

@implementation NSObject (Calculate)


+ (int)kx_makeCalculate:(void (^)(CalculateManager *))block{

    CalculateManager *manager = [[CalculateManager alloc] init];
    
    block(manager);
    
    return manager.result;
    
}

@end
#pragma mark -----------------------------------------------

#pragma mark ------ CalculateManager.h
//  01-鏈式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface CalculateManager : NSObject


/** 計算結(jié)果 */
@property (nonatomic , assign)  int result;

//-(instancetype)add:(int)value;


//返回值必須是類對象本身
- (CalculateManager *(^)(int))add;


@end

#pragma mark -----------------------------------------------

#pragma mark ------ CalculateManager.m
//
//  CalculateManager.m
//  01-鏈式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import "CalculateManager.h"

@implementation CalculateManager

//-(instancetype)add:(int)value{
//
//    _result += value;
//    
//    return self;
//
//}


-(CalculateManager * (^)(int))add{
    
    return ^(int value){
        _result += value;
        return self;
    };
    
}

@end

#pragma mark -----------------------------------------------

3.4 響應(yīng)式編程思想:不需要考慮調(diào)用順序,只需要知道考慮結(jié)果全景,類似于蝴蝶效應(yīng)耀石,產(chǎn)生一個事件,會影響很多東西爸黄,這些事件像流一樣的傳播出去滞伟,然后影響結(jié)果,借用面向?qū)ο蟮囊痪湓捒还螅f物皆是流梆奈。

  • 代表:KVO運用。

  • 練習二:KVO底層實現(xiàn)称开。

  KVO底層實現(xiàn):就是去判斷有沒有調(diào)用一個對象的set方法
   1.首先動態(tài)創(chuàng)建當前對象類的一個派生類(即:子類): NSKVONotifying_Person亩钟,做KVO
   2.修改當前對象的isa指針 -> NSKVONotifying_Person
   3.只奧調(diào)用對象的set方法乓梨,就會調(diào)用 NSKVONotifying_Person 的set方法
   4.重寫 NSKVONotifying_Person 的 set 方法(本質(zhì)賦值)。
       4.1:調(diào)用父類賦值[super set:];
       4.2:通知觀察者,告訴你屬性改變
KVO底層實現(xiàn)的過程
#pragma mark -------- ViewController.m

//  ViewController.m
//  02-響應(yīng)式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import "ViewController.h"
#import "Person.h"
#import "NSObject+KVO.h"

@interface ViewController ()
/**
 *  
 */
@property (nonatomic , strong)  Person *person;

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    Person *person = [[Person alloc] init];
    
    _person = person;
    
    //給person添加觀察者
    [person kx_addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];

    //1.只要 person 的 age 屬性一改變,就會調(diào)用觀察者的 observeValueForKeyPath
    
    //KVO底層實現(xiàn):
    //1.首先動態(tài)創(chuàng)建當前對象類的一個派生類(即:子類): NSKVONotifying_Person笙蒙,做KVO
    //2.修改當前對象的isa指針 -> NSKVONotifying_Person
    //3.只奧調(diào)用對象的set方法浇揩,就會調(diào)用 NSKVONotifying_Person 的set方法
    //4.重寫 NSKVONotifying_Person 的 set 方法(本質(zhì)賦值)。
        //4.1:調(diào)用父類賦值[super set:];
        //4.2:通知觀察者,告訴你屬性改變
 }


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    _person.age++;
    
}

//只要person.name的值已改變就會調(diào)用

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{

    NSLog(@"%d",_person.age);
    
}
#pragma mark -----------------------------------------------
#pragma mark ----------Person.h
//  Person.h
//  02 - 響應(yīng)式編程思想
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject

/** age  */
@property (nonatomic , assign)  int  age;

@end
#pragma mark -----------------------------------------------

#pragma mark ----------NSObject+KVO.h
//  NSObject+KVO.h
//  02-響應(yīng)式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.

#import <Foundation/Foundation.h>

@interface NSObject (KVO)
- (void)kx_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;

@end
#pragma mark -----------------------------------------------

#pragma mark ----------NSObject+KVO.m
//
//  NSObject+KVO.m
//  02-響應(yīng)式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import "NSObject+KVO.h"
#import <objc/message.h>
#import "KXKVONotifying_Person.h"

NSString * const observerKey = @"observer";

@implementation NSObject (KVO)

-(void)kx_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context{

    /**
     KVO底層實現(xiàn):
        1.首先動態(tài)創(chuàng)建當前對象類的一個派生類(即:子類): KXKVONotifying_Person,做KVO
        2.修改當前對象的isa指針 -> KXKVONotifying_Person
        3.只奧調(diào)用對象的set方法,就會調(diào)用 KXKVONotifying_Person 的set方法
        4.重寫 KXKVONotifying_Person 的 set 方法(本質(zhì)賦值)蝠筑。
           4.1:調(diào)用父類賦值[super set:];
           4.2:通知觀察者,告訴你屬性改變
     */
    
         //本質(zhì);就是修改當前對象的isa指針的類名
         //self:kx_addObserver方法的調(diào)用者即:person
         object_setClass(self, [KXKVONotifying_Person class]);
    
    
         //把觀察者保存到當前對象里(動態(tài)添加屬性)
         /**
         <#id object#>:給那個對象添加關(guān)聯(lián)
         <#const void *key#>:屬性名
         <#id value#>:關(guān)聯(lián)值
         <#objc_AssociationPolicy policy#>:策略:是assign,retian...
          */
    
         objc_setAssociatedObject(self, (__bridge const void *)(observerKey), observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}
@end
#pragma mark -----------------------------------------------
#pragma mark ----------KXKVONotifying_Person.m
//  KXKVONotifying_Person.m
//  02-響應(yīng)式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import "KXKVONotifying_Person.h"

#import <objc/message.h>

extern NSString *const observerKey;

@implementation KXKVONotifying_Person

- (void)setAge:(int)age{

    [super setAge:age];

    //通知觀察者揩懒,屬性改變
    id observer = objc_getAssociatedObject(self, observerKey);
    
    // 調(diào)用觀察者的方法
    [observer observeValueForKeyPath:@"age" ofObject:self change:nil context:nil];

}

@end
#pragma mark -----------------------------------------------

3.5 函數(shù)式編程思想:是把操作盡量寫成一系列嵌套的函數(shù)或者方法調(diào)用什乙。

  • 函數(shù)式編程本質(zhì):就是往方法中傳入Block,方法中嵌套Block調(diào)用,把代碼聚合起來管理

  • 函數(shù)式編程特點:每個方法必須有返回值(本身對象),把函數(shù)或者Block當做參數(shù),block參數(shù)(需要操作的值)block返回值(操作結(jié)果)

  • 代表:ReactiveCocoa已球。

  • 練習三:用函數(shù)式編程實現(xiàn)稳强,寫一個加法計算器,并且加法計算器自帶判斷是否等于某個值.


#pragma mark -----------ViewController.m
//  ViewController.m
//  03-函數(shù)式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

/**
 * 函數(shù)式編程思想:把一個操作寫成一系列方法
 * 需求:寫一個加法計算器,并且加法計算器自帶判斷是否等于某個值
 */

#import "ViewController.h"
#import "Caculator.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Caculator *caculator = [[Caculator alloc] init];
    //10 + 20 + 29
    
//    [[[caculator add:10] add:20] add:29];
    
   BOOL isEqule = [[[caculator add:^int(int result) {
        //把計算的事情寫到block
        
        result += 10;
        result += 30;
        result += 20;
        result += 40;
        
        return result;
        
    }] equle:^BOOL(int result) {
        
        // 判斷結(jié)果是否 等于 100
        return  result ==100;
        
    }] isEqule];
    
    NSLog(@"%d",isEqule);
    
}

@end
#pragma mark -------------------------------
#pragma mark ----------- Caculator.h
//
//  Caculator.h
//  03-函數(shù)式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import <Foundation/Foundation.h>
@interface Caculator : NSObject

/** 計算結(jié)果 */
@property (nonatomic , assign)  int result;
@property (nonatomic , assign)  BOOL isEqule;

//- (instancetype)add:(int)num;

- (instancetype)add:(int(^)(int result))block;
- (instancetype)equle:(BOOL(^)(int result))block;
@end
#pragma mark -------------------------------


#pragma mark ---------- Caculator.m
//
//  Caculator.m
//  03-函數(shù)式編程思想
//
//  Copyright ? 2017年 徐sir. All rights reserved.
//

#import "Caculator.h"
@implementation Caculator

//- (instancetype)add:(int)num{
//
//
//    _result += num;
//    
//    return self;
//    
//
//}

- (instancetype)add:(int (^)(int result))block{
   _result = block(_result);
    return  self;
}

- (instancetype)equle:(BOOL (^)(int))block{
    _isEqule = block(_result);  
    return self;
}
@end
#pragma mark -------------------------------

4.ReactiveCocoa編程思想

ReactiveCocoa結(jié)合了幾種編程風格:

  • 函數(shù)式編程(Functional Programming)

  • 響應(yīng)式編程(Reactive Programming)

所以和悦,你可能聽說過ReactiveCocoa被描述為函數(shù)響應(yīng)式編程(FRP)框架退疫。

以后使用RAC解決問題,就不需要考慮調(diào)用順序鸽素,直接考慮結(jié)果褒繁,把每一次操作都寫成一系列嵌套的方法中,使代碼高聚合馍忽,方便管理棒坏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市遭笋,隨后出現(xiàn)的幾起案子坝冕,更是在濱河造成了極大的恐慌,老刑警劉巖瓦呼,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喂窟,死亡現(xiàn)場離奇詭異,居然都是意外死亡央串,警方通過查閱死者的電腦和手機磨澡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來质和,“玉大人稳摄,你說我怎么就攤上這事∷撬蓿” “怎么了厦酬?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵胆描,是天一觀的道長。 經(jīng)常有香客問我仗阅,道長袄友,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任霹菊,我火速辦了婚禮,結(jié)果婚禮上支竹,老公的妹妹穿的比我還像新娘旋廷。我一直安慰自己,他們只是感情好礼搁,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布饶碘。 她就那樣靜靜地躺著,像睡著了一般馒吴。 火紅的嫁衣襯著肌膚如雪扎运。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天饮戳,我揣著相機與錄音豪治,去河邊找鬼。 笑死扯罐,一個胖子當著我的面吹牛负拟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歹河,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼掩浙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了秸歧?” 一聲冷哼從身側(cè)響起厨姚,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎键菱,沒想到半個月后谬墙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡经备,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年芭梯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弄喘。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡玖喘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蘑志,到底是詐尸還是另有隱情累奈,我是刑警寧澤贬派,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站澎媒,受9級特大地震影響搞乏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜戒努,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一请敦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧储玫,春花似錦侍筛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至端礼,卻和暖如春禽笑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蛤奥。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工佳镜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凡桥。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓邀杏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唬血。 傳聞我的和親對象是個殘疾皇子望蜡,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容