RAC_4.常用用法

4.常用用法 4.1 代替代理

JJView *view = [[JJView alloc]init]; view.backgroundColor = [UIColor yellowColor]; view.frame = CGRectMake(10, 64, 400, 500); [self.view addSubview:view]; RACSignal *signal = [view rac_signalForSelector:@selector(didClickButton:)]; [signal subscribeNext:^(RACTuple *_Nullable x) { NSLog(@"%@",x); [x.rac_sequence.signal subscribeNext:^(id_Nullable x) { if ([x isKindOfClass:[UIButton class]]) { UIButton *btn = (UIButton *)x; dispatch_async(dispatch_get_main_queue(), ^{ self.view.backgroundColor = btn.backgroundColor; }); } }]; }];

4.2 代替KVO
首先在这里我们要监听self.viewframe属性值的变化
JJView *view = [[JJView alloc]init]; view.backgroundColor = [UIColor yellowColor]; view.frame = CGRectMake(10, 64, 100, 100); [self.view addSubview:view]; [view rac_observeKeyPath:@"frame" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { //回调 NSLog(@"value%@---%@",value,change); }]; self.view = view;

touchesBegan:方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { static int x = 50; x++; self.view.frame = CGRectMake(x, 64, 200, 200); }

运行如图:

RAC_4.常用用法
文章图片
image
更简便的方法
JJView *view = [[JJView alloc]init]; view.backgroundColor = [UIColor yellowColor]; view.frame = CGRectMake(10, 64, 100, 100); [self.view addSubview:view]; self.view = view; RACSignal *signal = [view rac_valuesForKeyPath:@"frame" observer:nil]; [signal subscribeNext:^(id_Nullable x) { NSLog(@"%@",x); }];

运行如下图:

RAC_4.常用用法
文章图片
image 4.3 监听
  • 监听UIButton
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(10, 100, 100, 50)]; [self.view addSubview:btn]; [btn setBackgroundColor:[UIColor blackColor]]; [btn setTitle:@"点点" forState:UIControlStateNormal]; RACSignal *signal = [btn rac_signalForControlEvents:(UIControlEventTouchUpInside)]; [signal subscribeNext:^(id_Nullable x) { NSLog(@"%@",x); }];

  • 监听UITextField
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(10, 100, 100, 50)]; textField.backgroundColor = [UIColor blueColor]; [self.view addSubview:textField]; [textField.rac_textSignal subscribeNext:^(NSString * _Nullable x) { NSLog(@"%@",x); }];

运行如下:

RAC_4.常用用法
文章图片
image 4.4 代替通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) { NSLog(@"%@",x); }];

运行如下

RAC_4.常用用法
文章图片
image 4.5 代替NSTimer
在我们以往使用NSTimer 做定时循环执行的时候,
【RAC_4.常用用法】[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
正常情况下运行

RAC_4.常用用法
文章图片
image 大家有没有遇到过,如果timerMethod正在执行,而此时如果有UI事件的触发,比如滚动我们的屏幕,我们timerMethod执行将会被暂停执行,一旦UI事件执行完毕,timerMethod又会开始执行。原因是我们的NSTimer的事件是交给Runloop去处理,那么Runloop在执行的时候UI模式具有最高优先权。
那要解决这种问题怎么办呢?大家可能会想到,把他放到子线程中去执行, 开启runloop循环。
  • 解决方式①——开启runloop循环
if (@available(iOS 10.0, *)) { NSThread * thread = [[NSThread alloc]initWithBlock:^{ NSTimer * timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES]; //Runloop模式 && 多线程!! //NSDefaultRunLoopMode 默认模式; //UITrackingRunLoopMode UI模式:只能被UI事件唤醒!! //NSRunLoopCommonModes占位模式:默认&UI模式 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; //开启runloop循环 [[NSRunLoop currentRunLoop] run]; }]; [thread start]; } else { // Fallback on earlier versions }

  • 解决方式②——GCD设置timer
//GCD设置timer dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0)); //GCD的事件单位是纳秒 dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0); dispatch_source_set_event_handler(timer, ^{ NSLog(@"我是timer"); NSLog(@"-----_%@",[NSThread currentThread]); }); //启动 dispatch_resume(timer); _timer = timer;

  • 解决方式③——RAC
@interface CommonUseViewControllerr () @property(nonatomic,strong)RACDisposable* timerDisposable; @end@implementation CommonUseViewController- (void)viewDidLoad { [super viewDidLoad]; _timerDisposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler scheduler]] subscribeNext:^(NSDate * _Nullable x) { NSLog(@"%@",[NSThread currentThread]); }]; } -(void)dealloc{ //取消订阅!! [_timerDisposable dispose]; } @end

倒计时
@interface CommonUseViewController ()@property(assign,nonatomic)int time; /***/ @property(nonatomic,strong)RACDisposable* disposable; /***/ @property(nonatomic,strong)RACSignal * signal; @end

UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(10, 64, 100, 50)]; [btn setBackgroundColor:[UIColor blueColor]]; [self.view addSubview:btn]; [btn setTitle:@"发送验证码" forState:UIControlStateNormal]; RACSignal *signal = [btn rac_signalForControlEvents:(UIControlEventTouchUpInside)]; [signal subscribeNext:^(UIButton *btn) { NSLog(@"%@",btn); btn.enabled = NO; //设置倒计时 self.time = 10; //每一秒进来 self.signal = [RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]]; self.disposable = [self.signal subscribeNext:^(NSDate * _Nullable x) { NSLog(@"%@",self); //时间先减少! _time--; //设置文字 NSString * btnText = _time > 0 ? [NSString stringWithFormat:@"请等待%d秒",_time] : @"重新发送"; [btn setTitle:btnText forState:_time > 0?(UIControlStateDisabled):(UIControlStateNormal)]; //设置按钮 if(_time > 0){ btn.enabled = NO; }else{ btn.enabled = YES; //取消订阅!! [_disposable dispose]; } }]; }];

    推荐阅读