美文网首页
RAC_4.常用用法

RAC_4.常用用法

作者: Iris_Fighting | 来源:发表于2018-04-04 15:56 被阅读16次

    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<UITouch *> *)touches withEvent:(UIEvent *)event {
        static int x = 50;
        x++;
        self.view.frame = CGRectMake(x, 64, 200, 200);
    }
    

    运行如图:

    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);
        }];
    

    运行如下图:


    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);
            
        }];
    

    运行如下:


    image

    4.4 代替通知

    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
            NSLog(@"%@",x);
        }];
    

    运行如下


    image

    4.5 代替NSTimer

    在我们以往使用NSTimer 做定时循环执行的时候,

    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];

    正常情况下运行


    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];
                }
            }];
        }];
    

    相关文章

      网友评论

          本文标题:RAC_4.常用用法

          本文链接:https://www.haomeiwen.com/subject/cpokhftx.html