ReactiveCocoa 学习笔记
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了ReactiveCocoa 学习笔记,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10596字,纯文字阅读大概需要16分钟。
内容图文
#pragma mark - 各种方便的block封装? ReactiveCocoa
/*
?概述:
?可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多个水龙头合并成一个新的水龙头(combineLatest:reduce:),这样只要其中的一个水龙头有玻璃球出来,这个新合并的水龙头就会得到这个球。
?具体使用:
?当一个signal被一个subscriber subscribe后,这个subscriber何时会被移除?答案是当subscriber被sendComplete或sendError时,或者手动调用[disposable dispose]。
?当subscriber被dispose后,所有该subscriber相关的工作都会被停止或取消,如http请求,资源也会被释放。
?Signal events是线性的,不会出现并发的情况,除非显示地指定Scheduler。所以-subscribeNext:error:completed:里的block不需要锁定或者synchronized等操作,其他的events会依次排队,直到block处理完成。
?Errors有优先权,如果有多个signals被同时监听,只要其中一个signal sendError,那么error就会立刻被传送给subscriber,并导致signals终止执行。相当于Exception。
?生成Signal时,最好指定Name, -setNameWithFormat: 方便调试。
?block代码中不要阻塞。
?*/
-(void)reactiveCocoaDemoAction{
//? ? __weak typeof(self) wSelf = self;
//? ? 因为RAC是基于KVO的,而NSMutableArray并不会在调用addObject或removeObject时发送通知
? ? //------------------------------------通知监听----------------------------------------
? ? [[[ NSNotificationCenter defaultCenter ] rac_addObserverForName:@"log_out"object:nil] subscribeNext:^(id x) {
? ? ? ? //? ? ? ? NSNotification* notification = (NSNotification*)x;
? ? ? ? //? ? ? ? int unreadClubMsgCount = 0;
? ? ? ? //? ? ? ? if (notification.object) {
? ? ? ? //? ? ? ? ? ? unreadClubMsgCount = [notification.object intValue];
? ? ? ? //? ? ? ? }
? ? ? ? //退出登录的通知。---"log_out"是自定义的
? ? }];
?? ?
? ? //退出登录后执行。。。。上面的通知方法就可以触发了。
? ? [[ NSNotificationCenterdefaultCenter]postNotificationName:@"log_out"object:nil];
?? ?
? ? //------------------------------------UITextField输入限制-----------------------------
? ? UITextField *textField;//自己写初始化
? ? [textField.rac_textSignalsubscribeNext:^(NSString* text) {
? ? ? ? if(text.length > 12){
? ? ? ? ? ? textField.text = [text substringToIndex:12];
? ? ? ? }
? ? }];
? ? //------------------------------------UIAlertView,UIActionSheet点击方法-----------------------------
? ? UIAlertView *alertView;//自己写初始化
? ? [[alertView rac_buttonClickedSignal] subscribeNext:^(id x) {
? ? ? ? if ([x integerValue] == 1) {//alert的按钮
?? ? ? ? ? ?
? ? ? ? }
? ? }];
? ? [alertView show];
? ? UIActionSheet* actionSheet ;
? ? [[actionSheet rac_buttonClickedSignal] subscribeNext:^(id x) {
? ? ? ? if ([x integerValue] == 1) {//actionSheet的按钮
?? ? ? ? ? ?
? ? ? ? }
? ? }];
//? ? [actionSheet showInView:self.view];
? ? //------------------------------------UIButton点击方法-----------------------------
? ? UIButton *button;//自己写初始化
? ? [[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
?? ? ? ?
? ? }];
? ? //点击事件拦截。
? ? [[[button rac_signalForControlEvents:UIControlEventTouchUpInside]filter:^BOOL(UIButton *button) {
? ? ? ? if ([button.currentTitleisEqualToString:@"sd"]) {
? ? ? ? ? ? returnYES;
? ? ? ? }else{
? ? ? ? ? ? returnNO;
? ? ? ? }
? ? }]subscribeNext:^(id x) {
? ? ? ? NSLog(@"点击事件");
? ? }];
? ? //------------------------------------segmentedControl-----------------------------
? ? UISegmentedControl *segmentedControl;
? ? [[segmentedControl rac_signalForControlEvents:UIControlEventValueChanged] subscribeNext:^(id x) {
?? ? ? ?
?? ? ? ?
? ? }];
?? ?
? ? //---------------------------------------------RAC-------------------------------------------
? ? //---------------------------------------------RACObserver-------------------------------------------
//? ? RAC() 可以将Signal发出事件的值赋值给某个对象的某个属性,其参数为对象名和属性名
//? ? RACObserve() 参数为对象名和属性名,新建一个Signal并对对象的属性的值进行观察,当值变化时Signal会发出事件
? ? //某个属性一发生变化就执行。
? ? [RACObserve(self, count) subscribeNext:^(id x) {
? ? ? ? if ([x integerValue] == 0) {
?? ? ? ? ? ?
? ? ? ? }elseif ([x integerValue] > 100){
?? ? ? ? ? ?
? ? ? ? }
? ? }];
? ?
? ? //返回Bool赋值给createEnabled
? ? RAC(self, createEnabled) = [RACSignalcombineLatest:@[RACObserve(self, password),RACObserve(self, passwordConfirm)]reduce:^(NSString *pwd,NSString *pwdConfirm) {
? ? ? ? return@([pwd isEqualToString:pwdConfirm]);
? ? }];
?? ?
?? //--------------------------------------------map 用法 --------------------------------------------
? ? //map 改变返回的类型给结果管道。
? ? [[self.textField.rac_textSignalmap:^id(NSString *text) {
? ? ? ? if ([text isEmptyString]) {
? ? ? ? ? ? return [UIColorwhiteColor];
? ? ? ? }else{
? ? ? ? ? ? return [UIColoryellowColor];
? ? ? ? }
? ? }]subscribeNext:^(UIColor *color) {
? ? ? ? self.textField.backgroundColor = color;
? ? }];
?? ?
? ? [[[ self . buttonrac_signalForControlEvents:UIControlEventTouchUpInside]map:^id(UIButton *button) {
? ? ? ? if ([button.currentTitleisEqualToString:@"按钮"]) {
? ? ? ? ? ? return [NSStringstringWithFormat:@"按钮"];
? ? ? ? }else{
? ? ? ? ? ? return [NSStringstringWithFormat:@"不是按钮"];
? ? ? ? }
? ? }]subscribeNext:^(NSString *resultString) {
? ? ? ? NSLog(@"%@",resultString);
? ? }];
? ? //--------------------------------------------filter 用法 --------------------------------------------
? ? //filter某个属性满足一定条件才执行。
? ? [[RACObserve(self, count) filter:^BOOL(id count) {//返回的是BOOL类型
? ? ? ? if ([count integerValue] == 5) {
? ? ? ? ? ? returnYES;
? ? ? ? }else{
? ? ? ? ? ? returnNO;
? ? ? ? }
? ? }] subscribeNext :^( id count) {//上面return YES 才走这里
? ? ? ? NSLog(@"数量为===%@",count);
? ? }];
?? ?
? ? //--------------------------------------------rac_command 用法 --------------------------------------------
? ? self .button.rac_command = [[RACCommandalloc]initWithSignalBlock:^RACSignal *(id input) {
? ? ? ? NSLog(@"按钮点击了。");
? ? ? ? //? ? ? ? [RACSignal return:@(6)];
? ? ? ? return [RACSignalempty];
? ? }];
?? ?
?? ?
? ? //----------------------------------------RACDisposable 用法 --------------------------------------------
?? ?
? ? RACSignal *backgrountColorSignal = [self.textField.rac_textSignalmap:^id(NSString *text) {
? ? ? ? if ([text isEmptyString]) {
? ? ? ? ? ? return [UIColorwhiteColor];
? ? ? ? }else{
? ? ? ? ? ? return [UIColorgreenColor];
? ? ? ? }
? ? }];
? ? //subscrbeNext: 返回的类型是 RACDisposable
? ? RACDisposable *subscription = [backgrountColorSignal subscribeNext:^(UIColor *color) {
? ? ? ? self.textField.backgroundColor = color;
? ? }];
?? ?
? ? //----------------------------------------combineLaster 用法 --------------------------------------------
? ? //将self.button.enables 属性和右边的signal sendNext 值绑定。
? ? RAC(self.button,enabled) = [RACSignalcombineLatest:@[self.password,self.textField.rac_textSignal,RACObserve(self, passwordConfirm)]reduce:^(NSString *password,NSString *textString,NSString *passwordConfirm){
? ? ? ? if ([password isEqualToString:passwordConfirm] && textString.length > 0) {
? ? ? ? ? ? return@(YES);
? ? ? ? }else{
? ? ? ? ? ? return@(NO);
? ? ? ? }
? ? }];
?? ?
? ? //----------------------------------------RACSignal创建使用--------------------------------------------
//? ? 当一个signal被一个subscriber subscribe后,这个subscriber何时会被移除?答案是当subscriber被sendComplete或sendError时,或者手动调用[disposable dispose]。
? ? RACSignal *signal = [RACSignalcreateSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
? ? ? ? NSLog(@"当前值");
? ? ? ? [subscriber sendNext:@"下个值"];
? ? ? ? [subscriber sendCompleted];
? ? ? ? returnnil;
? ? }];//创建了一个 signal 但是没有被subscribe 所有上面都不会发生。
?? ?
? ? //单独执行这句会输出? 当前值? 完成1
? ? [signal subscribeCompleted:^{
? ? ? ? NSLog(@"完成了1");
? ? }];
?? ?
? ? //单独执行这句会输出? 当前值 x2===下个值
? ? [signal subscribeNext:^(id x) {
? ? ? ? NSLog(@"x2===%@",x);
? ? }];
?? ?
? ? //单独执行这句会输出? 当前值 x3===下个值? 完成了3
? ? [signal subscribeNext:^(id x) {
? ? ? ? NSLog(@"x3====%@",x);
? ? } completed:^{
? ? ? ? NSLog(@"完成了3");
? ? }];
? ? //---------------------------------------- RACSignal merge zipWith------------------------------------
? ? RACSignal *signalA = [RACSignalcreateSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
? ? ? ? [subscriber sendNext:@"A"];
? ? ? ? returnnil;
? ? }];//创建了一个 signal 但是没有被subscribe 所有上面都不会发生。
?? ?
? ? RACSignal *signalB = [RACSignalcreateSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
? ? ? ? [subscriber sendNext:@"B"];
? ? ? ? returnnil;
? ? }];
?? ?
? ? RACSignal *mergeSignal = [signalA merge:signalB];//任何一个信号发出都会执行。
? ? [mergeSignal subscribeNext:^(id x) {
? ? ? ? NSLog(@"%@",x);? ///会两个输出: A? B
? ? }];
? ? RACSignal *zipSignal = [signalA zipWith:signalB];//两个信号都发出才会执行
? ? [zipSignal subscribeNext:^(id x) {
? ? ? ? NSLog ( @"%@" ,x);///会输出一个数组(A ,B) <RACTuple: 0x7fd61c82b1d0>
? ? }];
? ? RACSignal *combineSignal = [signalA combineLatestWith:signalB];
? ? [combineSignal subscribeNext:^(id x) {
? ? ? ? NSLog ( @"%@" ,x);//会输出一个数组(A ,B)? <RACTuple: 0x7fd61c82b1d0>
? ? }];
?? ?
? ? RACSignal *reduceSignal = [RACSignalcombineLatest:@[signalA,signalB]reduce:^id(NSString *str1,NSString *str2){
? ? ? ? return [NSStringstringWithFormat:@"%@ %@",str1,str2];
? ? }];
? ? [reduceSignal subscribeNext:^(id x) {
? ? ? ? NSLog(@"%@",x);//合并后的字符串 A B
? ? }];
?? ?
? ? //---------------------------------------- RACSubject 是 RACSignal 的子类------------------------------------
?? ?
//? ? subjects 表现为RACSubject类,可以认为是“可变的(mutable)”信号/自定义信号,它是嫁接非RAC代码到Signals世界的桥梁,很有用。嗯。。。这样讲还是很抽象,举个例子吧:
? ? RACSubject *letters = [RACSubjectsubject];
? ? [letters sendNext:@"a"];
//? ? 可以看到@"a"只是一个NSString对象,要想在水管里顺利流动,就要借RACSubject的力。
?? ?
? ? //---------------------------------------- RACSequence有个属性是 RACSignal---------------------------
//? ? sequence 表现为RACSequence类,可以简单看做是RAC世界的NSArray,RAC增加了-rac_sequence方法,可以使诸如NSArray这些集合类(collection classes)直接转换为RACSequence来使用。
? ? NSArray *arr = [NSArrayarrayWithObjects:@"arr1",@"arr2", nil];
? ? NSMutableArray *array = [NSMutableArrayarray];
? ? RACSequence *sequence = [arr rac_sequence];
? ? [[[sequence.signalmap:^id(id value) {
? ? ? ? [array addObject:value];
? ? ? ? return array;
? ? }] filter:^BOOL(NSArray *resultArray) {
? ? ? ? if (resultArray.count < 2) {
? ? ? ? ? ? returnNO;
? ? ? ? }else{
? ? ? ? ? ? returnYES;
? ? ? ? }
? ? }] subscribeNext:^(id x) {
? ? ? ? NSLog(@"x===%@",x);
? ? }];
?? ?
? ? //---------------------------------------- scheduler 定时器------------------------------------
//? ? scheduler 表现为RACScheduler类,类似于GCD,but schedulers support cancellationbut schedulers support cancellation, and always execute serially
?? ?
? ? /**
?? ? *??@brief??创建一个定时器信号,每三秒发出一个当时日期值。一共发5次。
?? ? */
? ? RACSignal *signalInterval = [ RACSignalinterval:3.0onScheduler:[RACSchedulermainThreadScheduler]];
? ? signalInterval = [signalInterval take:5];//总共5次。
? ? [signalInterval subscribeNext:^(id x) {
? ? ? ? NSLog ( @"x====%@" ,x);///x====2015-12-30 04:05:50 +0000
? ? }];
}
原文:http://zhangmingwei.iteye.com/blog/2267631
内容总结
以上是互联网集市为您收集整理的ReactiveCocoa 学习笔记全部内容,希望文章能够帮你解决ReactiveCocoa 学习笔记所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。