RAC整理

RAC常用的方法滑凉,搭配@weakify(self); @weakify(self);

    1. 通知
# RAC中的通知不需要手動remove observer,其內(nèi)部已經(jīng)實現(xiàn)
  @weakify(self);
 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:kNotificationName object:nil] 
  subscribeNext:^(NSNotification * _Nullable x) {
        @strongify(self);

    }];

    1. control
# control的通用方法
 @weakify(self);
 [[button rac_signalForControlEvents:UIControlEventTouchUpOutside] subscribeNext:^(__kindof UIControl * _Nullable  x) {
        @strongify(self);

    }];
# 監(jiān)聽textfild的UIControlEventEditingChanged事件
# 方式一:
[[textFild rac_signalForControlEvents:UIControlEventEditingChanged] subscribeNext:^(__kindof UIControl * _Nullable  x){
    NSLog(@"change");
}];
# 方式二:
[[self.textFild rac_textSignal] subscribeNext:^(NSString *x) {
    NSLog(@"%@",x);
}];
//這樣就是每次改變TextFild都輸出改變后的結(jié)果
    1. Gesturer
# 再比如給我們的某個label添加一個手勢動作贫橙,我們也可以用簡單的RAC代碼完成
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
[[tap rac_gestureSignal] subscribeNext:^(__kindof   UIGestureRecognizer  * _Nullable x) {
    NSLog(@"tap");
}];
[self.view addGestureRecognizer:tap];
    1. 代理

用RAC寫代理是有局限的贪婉,它只能實現(xiàn)返回值為void的代理方法,RAC為我們提供了一個rac_signalForSelector: fromProtoc:方法幫我們實現(xiàn)代理

# alert方式一:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC TEST" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
[[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple *tuple) {
 # tuple封裝了方法的參數(shù),可以取出參數(shù)對應(yīng)的值
    NSLog(@"%@",tuple.first);
 #可以看出tuple.second是點擊Item的Index
    NSLog(@"%@",tuple.second);
    NSLog(@"%@",tuple.third);
}];
[alertView show];
#查看RACTuple
@interface RACTuple : NSObject <NSCoding, NSCopying, NSFastEnumeration>

@property (nonatomic, readonly) NSUInteger count;

/// These properties all return the object at that index or nil if the number of 
/// objects is less than the index.
@property (nonatomic, readonly, nullable) id first;
@property (nonatomic, readonly, nullable) id second;
@property (nonatomic, readonly, nullable) id third;
@property (nonatomic, readonly, nullable) id fourth;
@property (nonatomic, readonly, nullable) id fifth;
@property (nonatomic, readonly, nullable) id last;

2021-03-19 12:24:29.114 RACStudyTest[5003:388870] <UIAlertView: 0x7ff260c90c70; frame = (0 0; 0 0); layer = <CALayer: 0x7ff260c91030>>
2021-03-19 12:24:29.115 RACStudyTest[5003:388870] 1
2021-03-19 12:24:29.115 RACStudyTest[5003:388870] (null)
# alert方式二
[[alertView rac_buttonClickedSignal] subscribeNext:^(id x) {
#  這里的x是點擊Item的Index
    NSLog(@"%@",x);
}];
    1. kvo

RAC中得KVO大部分都是宏定義卢肃,所以代碼異常簡潔疲迂,簡單來說就是 RACObserve(TARGET, KEYPATH)這種形式,TARGET是監(jiān)聽目標莫湘,KEYPATH是要觀察的屬性值


 @weakify(self);
[RACObserve(object, propertyChanged) subscribeNext:^(id propertyChangedValue) {
        @strongify(self);    

}];
  [[RACSignal combineLatest:@[RACObserve(self.messageViewController, unReadMessageCount),RACObserve(self.friendsVc, unReadMessageCount),RACObserve(self, unReadSystemCount)]] subscribeNext:^(RACTuple *x) {
        @strongify(self);
        NSInteger first = ((NSNumber *)x.first).integerValue;
        NSInteger second = ((NSNumber *)x.second).integerValue;
        NSInteger third = ((NSNumber *)x.third).integerValue;
        JHTabBarController *tabbarVC = (JHTabBarController *)self.tabBarController;
        [tabbarVC.customTabBar hideBadgeOnItemIndex:3];//隱藏未讀小紅點
        if (first>0||second>0||third>0) {
            [tabbarVC.customTabBar showBadgeOnItemIndex:3 value:(first+second+third)];//顯示未讀小紅點
        }
    }];

RACSignal 封裝請求

- (RACSignal *)sendShareMessageWithModel:(JH_ChatRoomBaseModel *)messageModel {
    
    @weakify(self);
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        @strongify(self);
        
        [self addMessageModelToDatabase:messageModel];
        
        //通過Socket向服務(wù)器發(fā)送消息
        [self sendMessageToServerWithModel:messageModel];
        // 給訂閱者發(fā)送消息
        [subscriber sendNext:@(YES)];
        [subscriber sendCompleted];
        
        return nil;
    }];
}

RAC相關(guān)類

RACSignal的使用

   // 創(chuàng)建一個信號
   RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
       
       NSLog(@"創(chuàng)建一個信號");
       
       // 發(fā)送信號
       [subscriber sendNext:@"發(fā)送一個信號"];
       
       return nil;
   }];
   
   // 訂閱一個信號
   [signal subscribeNext:^(id  _Nullable x) {
       
       NSLog(@"訂閱一個信號");
       NSLog(@"訂閱到的: %@", x);
   }];
2017-07-22 17:37:09.294 RAC[66282:12633516] 創(chuàng)建一個信號
2017-07-22 17:37:09.295 RAC[66282:12633516] 訂閱一個信號
2017-07-22 17:37:09.295 RAC[66282:12633516] 訂閱到的: 發(fā)送一個信號

sendNext就把內(nèi)容傳遞到了Next的block中了

UITextField+RACSignalSupport.h

#import <UIKit/UIKit.h>

@class RACChannelTerminal<ValueType>;
@class RACSignal<__covariant ValueType>;

NS_ASSUME_NONNULL_BEGIN
# 
@interface UITextField (RACSignalSupport)
#  
- (RACSignal<NSString *> *)rac_textSignal;
# 用于雙向綁定
- (RACChannelTerminal<NSString *> *)rac_newTextChannel;

@end

NS_ASSUME_NONNULL_END

rac_textSignal

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 35)];
    
    textField.center          = self.view.center;
    textField.backgroundColor = [UIColor yellowColor];
    
    [[textField
        rac_textSignal]
        subscribeNext:^(NSString * _Nullable x) {
            
            NSLog(@"%@", x);
        }];
    
    [self.view addSubview:textField];

2017-07-23 22:55:45.686 RAC[70205:14118946] 1
2017-07-23 22:55:46.139 RAC[70205:14118946] 11
2017-07-23 22:55:46.798 RAC[70205:14118946] 111

rac_newTextChannel

@interface RACChannelTerminal<ValueType> : RACSignal<ValueType> <RACSubscriber>

- (instancetype)init __attribute__((unavailable("Instantiate a RACChannel instead")));

// Redeclaration of the RACSubscriber method. Made in order to specify a generic type.
- (void)sendNext:(nullable ValueType)value;

@end
#rac_newTextChannel效果跟rac_textSignal一樣, 那么它有什么特別的用法呢?
[[textField
        rac_newTextChannel]
        subscribeNext:^(NSString * _Nullable x) {
            
            NSLog(@"%@", x);
        }];
#rac_newTextChannel雙向綁定
    UITextField *textFieldA = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 35)];
    
    textFieldA.center          = self.view.center;
    textFieldA.backgroundColor = [UIColor yellowColor];
    
    [self.view addSubview:textFieldA];
    
    UITextField *textFieldB = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 35)];
    
    textFieldB.center          = CGPointMake(self.view.center.x, self.view.center.y + 50);
    textFieldB.backgroundColor = [UIColor yellowColor];
    
    [self.view addSubview:textFieldB];
    
    RACChannelTerminal *terminalA = [textFieldA rac_newTextChannel];
    RACChannelTerminal *terminalB = [textFieldB rac_newTextChannel];
    
    [terminalA subscribe:terminalB];
    [terminalB subscribe:terminalA];

#運行可以看到, 改變textFieldA的值textFieldB的值也會跟著改變, 反過來也一樣.

#這里如果要實現(xiàn)雙向綁定, 其實還有一個簡單的方法:
RACChannelTo(textFieldA, text) = RACChannelTo(textFieldB, text);

如果我們不僅僅想讓兩個綁定對象之間的值簡單的相等而已呢? 比如textFieldA的值是123的時候textFieldB的值要為321要怎么處理呢?
這里我們先說一個一會用到的方法: map(映射)

map方法尤蒿,將會創(chuàng)建一個和原來一模一樣的信號,只不過新的信號傳遞的值變?yōu)榱薭lock(value)幅垮。

[[[textField
        rac_textSignal]
        map:^id _Nullable(NSString * _Nullable value) {
            
            if ([value isEqualToString:@"11"]) {
                
                return @"1";
            } else {
                
                return @"0";
            }
        }] subscribeNext:^(id  _Nullable x) {
            
            NSLog(@"%@", x);
        }];

運行看看, 當(dāng)我們輸入1, 會打印0, 輸入11的時候會打印1, 這里就是把傳遞的值從textField的text轉(zhuǎn)變成為我們的1 和 0;

那么要實現(xiàn)上面的123 到 321可以這樣寫:

    RACChannelTerminal *terminalA = [textFieldA rac_newTextChannel];
    RACChannelTerminal *terminalB = [textFieldB rac_newTextChannel];
    
    [[terminalA
        map:^id _Nullable(id  _Nullable value) {
            
            if ([value isEqualToString:@"123"]) {
                
                return @"321";
            }
            
            return value;
        }]
        subscribe:terminalB];

    [terminalB subscribe:terminalA];

大家可以自己運行看看效果, 當(dāng)textFieldA輸入123的時候textFieldB會變?yōu)?21

 RAC(self.sureBtn, enabled) = [RACSignal combineLatest:@[self.phoneTF.rac_textSignal, self.codeTF.rac_textSignal] reduce:^id (NSString *phoneNumber, NSString *code){
        @strongify(self);
        if (phoneNumber.length==11 && code.length==6) {
            self.sureBtn.alpha = 1;
            return @(YES);
        } else {
            self.sureBtn.alpha = 0.6;
            return @(NO);
        }
    }];

UIActionSheet+RACSignalSupport.h

#import <UIKit/UIKit.h>

@class RACDelegateProxy;
@class RACSignal<__covariant ValueType>;

NS_ASSUME_NONNULL_BEGIN

@interface UIActionSheet (RACSignalSupport)

@property (nonatomic, strong, readonly) RACDelegateProxy *rac_delegateProxy;

- (RACSignal<NSNumber *> *)rac_buttonClickedSignal;

@end

rac_buttonClickedSignal

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"RAC ActionSheet" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"OK" otherButtonTitles:@"Other", nil];
    
    [[actionSheet
        rac_buttonClickedSignal]
     subscribeNext:^(NSNumber * _Nullable x) {
         
         NSLog(@"%@", x);
     }];
    
    [actionSheet showInView:self.view];
  #運行看看, x是actionSheet上按鈕的編號, 我們拿到編號就可以做響應(yīng)的事件處理了.

UIAlertView+RACSignalSupport.h

@interface UIAlertView (RACSignalSupport)

@property (nonatomic, strong, readonly) RACDelegateProxy *rac_delegateProxy;


- (RACSignal<NSNumber *> *)rac_buttonClickedSignal;


- (RACSignal<NSNumber *> *)rac_willDismissSignal;

@end

NS_ASSUME_NONNULL_END
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC Alert" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
    
    [[alert
        rac_buttonClickedSignal]
        subscribeNext:^(NSNumber * _Nullable x) {
            
            NSLog(@"click: x");
        }];
    
    [[alert
        rac_willDismissSignal]
        subscribeNext:^(NSNumber * _Nullable x) {
            
            NSLog(@"dismiss: %@", x);
        }];
    
    [alert show];

UIControl+RACSignalSupport.h

#import <UIKit/UIKit.h>

@class RACSignal<__covariant ValueType>;

NS_ASSUME_NONNULL_BEGIN

@interface UIControl (RACSignalSupport)

- (RACSignal<__kindof UIControl *> *)rac_signalForControlEvents:(UIControlEvents)controlEvents;

@end

NS_ASSUME_NONNULL_END
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    
    [button setFrame:CGRectMake(0, 0, 100, 35)];
    [button setCenter:self.view.center];
    [button setBackgroundColor:[UIColor yellowColor]];
    [button setTitle:@"按鈕" forState:UIControlStateNormal];
    
    [[button
        rac_signalForControlEvents:UIControlEventTouchUpInside]
        subscribeNext:^(__kindof UIControl * _Nullable x) {
            
            NSLog(@"點擊了按鈕");
            x.backgroundColor = [UIColor redColor];
        }];
    
    [self.view addSubview:button];

UIDatePicker+RACSignalSupport.h

#import <UIKit/UIKit.h>

@class RACChannelTerminal<ValueType>;

NS_ASSUME_NONNULL_BEGIN

@interface UIDatePicker (RACSignalSupport)

- (RACChannelTerminal<NSDate *> *)rac_newDateChannelWithNilValue:(nullable NSDate *)nilValue;

@end

NS_ASSUME_NONNULL_END
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 160)];
    datePicker.center = self.view.center;
    datePicker.backgroundColor = [UIColor redColor];
    
    [self.view addSubview:datePicker];
    
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 180, 35)];
    textField.center = CGPointMake(self.view.center.x, self.view.center.y - 100);
    textField.backgroundColor = [UIColor yellowColor];
    
    [self.view addSubview:textField];
    
    
    RACChannelTerminal *datePickerTerminal = [datePicker rac_newDateChannelWithNilValue:[NSDate date]];
    RACChannelTerminal *textFieldTerminal  = [textField rac_newTextChannel];
    
    [[datePickerTerminal
        map:^id _Nullable(id  _Nullable value) {
            NSLog(@"%@", value);
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            return [dateFormatter stringFromDate:value];
        }]
        subscribe:textFieldTerminal];
截屏2021-03-19 下午2.46.31.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腰池,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子忙芒,更是在濱河造成了極大的恐慌示弓,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呵萨,死亡現(xiàn)場離奇詭異奏属,居然都是意外死亡,警方通過查閱死者的電腦和手機甘桑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門拍皮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人跑杭,你說我怎么就攤上這事铆帽。” “怎么了德谅?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵爹橱,是天一觀的道長。 經(jīng)常有香客問我窄做,道長愧驱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任椭盏,我火速辦了婚禮组砚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘掏颊。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布录平。 她就那樣靜靜地躺著讯私,像睡著了一般。 火紅的嫁衣襯著肌膚如雪准浴。 梳的紋絲不亂的頭發(fā)上事扭,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音乐横,去河邊找鬼求橄。 笑死,一個胖子當(dāng)著我的面吹牛晰奖,可吹牛的內(nèi)容都是我干的谈撒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼匾南,長吁一口氣:“原來是場噩夢啊……” “哼啃匿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蛆楞,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤溯乒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后豹爹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裆悄,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年臂聋,在試婚紗的時候發(fā)現(xiàn)自己被綠了光稼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片或南。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖艾君,靈堂內(nèi)的尸體忽然破棺而出采够,到底是詐尸還是另有隱情,我是刑警寧澤冰垄,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布蹬癌,位于F島的核電站,受9級特大地震影響虹茶,放射性物質(zhì)發(fā)生泄漏逝薪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一蝴罪、第九天 我趴在偏房一處隱蔽的房頂上張望董济。 院中可真熱鬧,春花似錦要门、人聲如沸感局。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽询微。三九已至,卻和暖如春狂巢,著一層夾襖步出監(jiān)牢的瞬間撑毛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工唧领, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留藻雌,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓斩个,卻偏偏與公主長得像胯杭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子受啥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

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