標籤(空格分隔): RAC FRP 函數語言程式設計 響應式程式設計
本文內容僅適用於ReactiveCocoa v2.5
關於函式響應式程式設計(FRP),可以參考
- What is (functional) reactive programming?
- Specification for a Functional Reactive Programming language
Streams of values over time
ReactiveCocoa repo上最簡單的一句話對FRP做了本質的描述,而repo本身提供的是APIs of composing and transforming streams of values,而Streams of values的抽象在ReactiveCocoa中應該是RACStream,而composing and transforming是本文的重點。
先解釋ReactiveCocoa中的兩個基本概念
-
訊號(Signal) a signal is a steam of values,signals can be transformed, combined,etc.
-
訂閱者(Subscriber) a subscriber subscribes to a signal. RAC lets blocks,objects, and properties subscribe to signals
filter
RACSignal *signal = [@[ @1, @2, @3 ] rac_sequence].signal; signal = [signal filter:^BOOL(NSNumber *value) {
return value.integerValue % 2;
}];
[signal subscribeNext:^(NSNumber *value) {
NSLog(@"%@", value);
}];
複製程式碼
map
RACSignal *signal = [@[ @1, @2, @3 ] rac_sequence].signal;
signal = [signal map:^id(NSNumber *value) {
return @(value.integerValue * 2);
}];
[signal subscribeNext:^(NSNumber *value) {
NSLog(@"%@", value);
}];
複製程式碼
merge
RACSignal *signal1 = [@[ @1, @2 ] rac_sequence].signal;
RACSignal *signal2 = [@[ @4, @5 ] rac_sequence].signal;
[[signal1 merge:signal2] subscribeNext:^(NSNumber *value) {
NSLog(@"%@", value);
}];
複製程式碼
combineLatest
RACSignal *signal1 = [@[ @1, @2 ] rac_sequence].signal;
RACSignal *signal2 = [@[ @3, @4 ] rac_sequence].signal;
[[signal1 combineLatestWith:signal2] subscribeNext:^(RACTuple *value) {
NSLog(@"%@", value);
}];
複製程式碼
combineLatest & reduce
RACSignal *signal1 = [@[ @1, @2 ] rac_sequence].signal;
RACSignal *signal2 = [@[ @3, @4 ] rac_sequence].signal;
[[[signal1 combineLatestWith:signal2]
reduceEach:^id(NSNumber *v1, NSNumber *v2) {
return @(v1.integerValue * v2.integerValue);
}] subscribeNext:^(RACTuple *value) {
NSLog(@"%@", value);
}];
複製程式碼
flatten
RACSignal *signal1 = [@[ @1, @2 ] rac_sequence].signal;
RACSignal *signal2 = [RACSignal return:signal1];
[[signal2 flatten] subscribeNext:^(NSNumber *value) {
NSLog(@"%@", value);
}];
複製程式碼
flattenMap
RACSignal *signal = [@[ @1, @2 ] rac_sequence].signal;
[[signal flattenMap:^RACStream *(NSNumber *value) {
return [RACSignal return:@(value.integerValue * 2)];
}] subscribeNext:^(NSNumber *value) {
NSLog(@"%@", value);
}];
複製程式碼
not replay
RACSubject *letters = [RACSubject subject];
RACSignal *signal = letters;
[signal subscribeNext:^(id x) {
NSLog(@"S1: %@", x);
}];
[letters sendNext:@"A"];
[signal subscribeNext:^(id x) {
NSLog(@"S2: %@", x);
}];
[letters sendNext:@"B"];
[letters sendNext:@"C"];
複製程式碼
replay
RACSubject *letters = [RACReplaySubject subject];
RACSignal *signal = letters;
[signal subscribeNext:^(id x) {
NSLog(@"S1: %@", x);
}];
[letters sendNext:@"A"];
[signal subscribeNext:^(id x) {
NSLog(@"S2: %@", x);
}];
[letters sendNext:@"B"];
[signal subscribeNext:^(id x) {
NSLog(@"S3: %@", x);
}];
[letters sendNext:@"C"];
複製程式碼
replayLast
RACSubject *letters = [RACSubject subject];
RACSignal *signal = [letters replayLast];
[signal subscribeNext:^(id x) {
NSLog(@"S1: %@", x);
}];
[letters sendNext:@"A"];
[signal subscribeNext:^(id x) {
NSLog(@"S2: %@", x);
}];
[letters sendNext:@"B"];
[signal subscribeNext:^(id x) {
NSLog(@"S3: %@", x);
}];
[letters sendNext:@"C"];
複製程式碼
replayLazily
RACSubject *letters = [RACSubject subject];
RACSignal *signal = [letters replayLazily];
[letters sendNext:@"A"];
[signal subscribeNext:^(id x) {
NSLog(@"S1: %@", x);
}];
[letters sendNext:@"B"];
[signal subscribeNext:^(id x) {
NSLog(@"S2: %@", x);
}];
[letters sendNext:@"C"];
[signal subscribeNext:^(id x) {
NSLog(@"S3: %@", x);
}];
[letters sendNext:@"D"];
複製程式碼
zip
RACSubject *letters = [RACSubject subject];
RACSubject *numbers = [RACSubject subject];
RACSignal *combined =
[RACSignal zip:@[ letters, numbers ]
reduce:^(NSString *letter, NSString *number) {
return [letter stringByAppendingString:number];
}];
// Outputs: A1 B2 C3
[combined subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
[letters sendNext:@"A"];
[letters sendNext:@"B"];
[letters sendNext:@"C"];
[numbers sendNext:@"1"];
[numbers sendNext:@"2"];
[numbers sendNext:@"3"];
複製程式碼
完整的原始碼可以在這裡找到 Demo
"-g"選項 : 檢視日誌緩衝區資訊;
"-b"選項 : 載入一個日誌緩衝區, 預設是 main, 下面詳解;
"-B"選項 : 以二進位制形式輸出日誌;
複製程式碼
如有任何智慧財產權、版權問題或理論錯誤,還請指正。
轉載請註明原作者及以上資訊。