iOS开发ReactiveCocoa(七):开发中常见用法


危楼高百尺,手可摘星辰。
不敢高声语,恐惊天上人。

——李白《夜宿山寺》

实际项目中的不同风格用法

参考常用的写法用RAC替代

控件赋值也可以这么样用(类似于cell中设置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
RAC(self.textLabel, text) = RACObserve(self, city.cityName); // 直接给label文字赋值
RAC(self.imgView, image) = [[[RACObserve(self, city.thumbnailData) // 直接给imageView 赋值
ignore:nil]
map:^id(id value) { // 转换图片
return [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
UIImage *image = [UIImage imageWithData:value];

[subscriber sendNext:image];
[subscriber sendCompleted];
return nil;
}]

subscribeOn:[RACScheduler scheduler]]
deliverOn:[RACScheduler mainThreadScheduler]]; // 主线程更新
}]
switchToLatest];

转模型也可以这么用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)initSearchSubscrition {
[[self.searchSignal deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(RACTuple *jsonSearchResult) {
NSDictionary *response;
if (jsonSearchResult.count) {
response = jsonSearchResult.first;
}
NSArray *rawArray = response[@"geoNames"];
self.cities = [[[rawArray.rac_sequence // 获取的数据转rac_sequence (里面都是信号)
map:^id(NSDictionary *rawDic) { // 转模型
NSMutableDictionary *dic = [(NSDictionary *)rawDic mutableCopy];
City *city = [MTLJSONAdapter modelOfClass:City.class fromJSONDictionary:dic error:nil];
[self downloadImageForCity:city];
return city;
}] array] mutableCopy]; // 放进数组中 并拷贝新生成一份
}];
[self.searchSignal subscribeError:^(NSError *error) {
self.statusMessage = @"offLine";
}];
}

代理方法也可以这么调

1
2
3
4
5
[[self rac_signalForSelector:@selector(didSaveDataCallback:) fromProtocol:@protocol(SaveDataCallBack)] subscribeNext:^(RACTuple *tuple) {
City *newCity = tuple.first;
[self.viewModel.cities insertObject:newCity atIndex:0];
[self.geoTbl reloadData];
}];

多个渠道请求数据都返回才能进行下一步 可以这么组装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
RACSignal *requestHot = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { 
NSLog(@"请求最热商品");
[subscriber sendNext:@"获取最热商品"];
return nil;
}];

RACSignal *requestNew = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"请求最新商品");
// [subscriber sendNext:@"获取最新商品"];
return nil;
}];

// Selector调用:当所有信号都发送数据的时候调用
// 数组存放信号
// Selector注意点:参数根据数组元素决定
// Selector方法参数类型,就是信号传递出来数据
[self rac_liftSelector:@selector(updateUI:data2:) withSignalsFromArray:@[requestHot,requestNew]];
}

// 只要两个请求都请求完成的时候才会调用
- (void)updateUI:(NSString *)data1 data2:(NSString *)data2 {
NSLog(@"%@ %@",data1,data2);
}

监听属性改变

1
2
// 设置Label 文字跟着 TextField的改变而改变
RAC(self.myLab, text) = self.myTF.rac_textSignal;
1
2
3
4
// 监听某一个属性的改变
[RACObserve(self.per, name) subscribeNext:^(NSString *name) {
// name 即 self.per.name
}];

数组

1
2
3
4
NSArray *array = @[@1, @2, @3, @4, @5];
[array.rac_sequence.signal subscribeNext:^(id x) {
// x 即 数组 array 的元素
}];
1
2
3
4
// 过滤 filter,并获取过滤后的数组
NSArray *filter = [[array.rac_sequence filter:^BOOL(id value) {
return [value integerValue] > 2;
}] array];
1
2
3
4
5
6
// 匹配、映射 map,变换元素并获取新数组
NSArray *map = [[array.rac_sequence map:^id(id value) {
NSInteger a = [value integerValue] * [value integerValue];
return [NSString stringWithFormat:@"%ld", a];

}] array];

字典

1
2
3
4
5
6
7
// rac_keySequence 和 rac_valueSequence 跟数组一样
// rac_sequence 需要 RACTupleUnpack 解包
NSDictionary *dic = @{@"name": @"lion", @"age": @18};
[dic.rac_sequence.signal subscribeNext:^(id x) {
RACTupleUnpack(NSString *key, NSString *value) = x;
NSLog(@"\r\nkey: %@\r\nvalue: %@", key, value);
}];
要不要鼓励一下😘