转载:http://ios.jobbole.com/82356/
前戏
我个人非常推崇ReactiveCocoa,它就像中国的太极,太极生两仪,两仪生四象,四象生八卦,八卦生万物。ReactiveCocoa是一个高度抽象的编程框架,它真的很抽象,初看你不知道它是要干嘛的,等你用上了之后,就发现,有了它你是想干嘛就干嘛,编码从未如此流畅。
在此我不会讲ReactiveCocoa的原理,因为不能讲明白的才叫抽象。我也不会提及相关概念。我只是让你看看我用着它是有多爽。
代码的四十八手
察值
你别动,你一动我就知道。
单边
你唱歌,我就跳舞。
textField的内容长度隐射成BOOL值,绑定到confirmButton的enable属性上面,当textField输入内容不为空的时候,confirmButton的enable = YES。
1
2
3
4
5
6
7
8
9
10
11
|
RACSignal
*signalA
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
[
subscriber
sendCompleted
]
;
return
nil
;
}
]
;
RAC
(
self
,
value
)
@H_502_87@=
[
signalA
map
@H_502_87@:
@H_502_87@^
id
(
NSString
@H_502_87@*
value
)
{
return
@"跳舞"
;
}
@H_773_404@
return
@""
;
}
]
;
|
双边
你向西,他就向东,他向左,你就向右。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
return
@"东"
;
}
return
value
;
}
]
subscribe
:channelB
]
;
return
@"右"
;
}
return
value
;
}
]
subscribe
:channelA
]
;
return
value
?
YES
: NO
;
NSLog
(
@"你向%@"
,
x
)
;
}
]
;
return
value
?
YES
: NO
;
NSLog
(
@"他向%@"
,
x
)
;
}
]
;
|
1
2
3
4
|
2015
@H_502_87@-
08
@H_502_87@-
15
20
@H_502_87@:
14
@H_502_87@:
46.544
Test
[
2440
@H_502_87@:
99901
]
你向西
2015
@H_502_87@-
08
@H_502_87@-
15
20
@H_502_87@:
14
@H_502_87@:
46.544
Test
[
2440
@H_502_87@:
99901
]
他向东
|
代理
你是程序员,你帮我写个app吧。
1
2
3
|
1
2
3
4
5
6
7
|
NSLog
(
@"花了一个月,app写好了"
)
;
}
]
;
[
self
makeAnApp
]
;
|
广播
知道你的频道,我就能听到你了。
连接
生活是一个故事接一个故事。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
RACSignal
*signalA
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
[
subscriber
sendCompleted
]
;
return
nil
;
}
]
;
RACSignal
*signalB
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
[
subscriber
sendCompleted
]
;
return
nil
;
}
]
;
NSLog
(
@"%@"
,
x
)
;
}
]
;
|
合并
污水都应该流入污水处理厂被处理。
1
2
3
4
5
6
7
8
9
10
11
|
RACSignal
*signalA
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
return
nil
;
}
]
;
RACSignal
*signalB
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
return
nil
;
}
]
;
[
[
RACSignal
merge
@H_502_87@:
@
[
signalA
,
signalB
]
]
subscribeNext
@H_502_87@:
@H_502_87@^
(
id
x
)
{
NSLog
(
@"处理%@"
,
x
)
;
}
]
;
|
组合
你是红的,我是黄的,我们就是红黄的,你是白的,我没变,我们是白黄的。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
RACSignal
*signalA
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
return
nil
;
}
]
;
RACSignal
*signalB
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
return
nil
;
}
]
;
[
[
RACSignal
combineLatest
@H_502_87@:
@
[
signalA
,
signalB
]
]
subscribeNext
@H_502_87@:
@H_502_87@^
(
RACTuple
@H_502_87@*
x
)
{
@H_655_3016@
RACTupleUnpack
(
NSString
*stringA
,
NSString
*stringB
)
@H_502_87@=
x
;
NSLog
(
@"我们是%@%@的"
,
stringA
,
stringB
)
;
}
]
;
|
压缩
你是红的,我是黄的,我们就是红黄的,你是白的,我没变,哦,那就等我变了再说吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
RACSignal
*signalA
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
return
nil
;
}
]
;
RACSignal
*signalB
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
return
nil
;
}
]
;
NSLog
(
@"我们是%@%@的"
,
stringB
)
;
}
]
;
|
映射
我可以点石成金。
归约
糖加水变成糖水。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
RACSignal
*sugarSignal
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
return
nil
;
}
]
;
RACSignal
*waterSignal
@H_502_87@=
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
return
nil
;
}
]
;
[
[
RACSignal
combineLatest
@H_502_87@:
@
[
sugarSignal
,
waterSignal
]
reduce
@H_502_87@:
@H_502_87@^
id
(
NSString
@H_502_87@*
sugar
,
NSString
*water
)
{
return
[
sugar
stringByAppendingString
:water
]
;
NSLog
(
@"%@"
,
x
)
;
}
]
;
|
过滤
未满十八岁,禁止进入。
扁平
打蛋液,煎鸡蛋,上盘。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
[
[
[
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
NSLog
(
@"打蛋液"
)
;
[
subscriber
sendCompleted
]
;
return
nil
;
return
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
NSLog
(
@"把%@倒进锅里面煎"
,
value
)
;
[
subscriber
sendCompleted
]
;
return
nil
;
}
]
;
return
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
NSLog
(
@"把%@装到盘里"
,
value
)
;
[
subscriber
sendCompleted
]
;
return
nil
;
}
]
;
NSLog
(
@"%@"
,
x
)
;
}
]
;
|
1
2
3
4
|
2015
@H_502_87@-
08
@H_502_87@-
16
20
@H_502_87@:
39
@H_502_87@:
34.786
Test
[
1226
@H_502_87@:
34386
]
打蛋液
2015
@H_502_87@-
08
@H_502_87@-
16
20
@H_502_87@:
39
@H_502_87@:
34.787
Test
[
1226
@H_502_87@:
34386
]
把蛋液倒进锅里面煎
|
秩序
把大象塞进冰箱只需要三步:打开冰箱门,把大象塞进冰箱,关上冰箱门。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
[
[
[
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
NSLog
(
@"打开冰箱门"
)
;
[
subscriber
sendCompleted
]
;
return
nil
;
return
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
NSLog
(
@"把大象塞进冰箱"
)
;
[
subscriber
sendCompleted
]
;
return
nil
;
}
]
;
return
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
NSLog
(
@"关上冰箱门"
)
;
[
subscriber
sendCompleted
]
;
return
nil
;
}
]
;
NSLog
(
@"把大象塞进冰箱了"
)
;
}
]
;
|
1
2
3
4
|
2015
@H_502_87@-
08
@H_502_87@-
16
20
@H_502_87@:
45
@H_502_87@:
27.724
Test
[
1334
@H_502_87@:
37870
]
打开冰箱门
2015
@H_502_87@-
08
@H_502_87@-
16
20
@H_502_87@:
45
@H_502_87@:
27.725
Test
[
1334
@H_502_87@:
37870
]
把大象塞进冰箱
@H_502_6192@
2015
@H_502_87@-
08
@H_502_87@-
16
20
@H_502_87@:
45
@H_502_87@:
27.725
Test
[
1334
@H_502_87@:
37870
]
关上冰箱门
|
命令
我命令你马上投降。
1
2
3
4
5
6
7
8
|
RACCommand
*aCommand
@H_502_87@=
[
[
RACCommand
alloc
]
initWithSignalBlock
@H_502_87@:
@H_502_87@^
RACSignal
@H_502_87@*
(
id
input
)
{
return
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
NSLog
(
@"我投降了"
)
;
[
subscriber
sendCompleted
]
;
return
nil
;
}
]
;
}
]
;
[
aCommand
execute
:nil
]
;
|
延迟
等等我,我还有10秒钟就到了。
重放
一次制作,多次观看。
1
2
3
4
5
6
7
8
9
10
11
|
定时
每隔8个小时服一次药。
超时
等了你一个小时了,你还没来,我走了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[
[
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
[
[
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
NSLog
(
@"我快到了"
)
;
[
subscriber
sendNext
:nil
]
;
[
subscriber
sendCompleted
]
;
return
nil
;
[
subscriber
sendNext
:nil
]
;
[
subscriber
sendCompleted
]
;
}
]
;
return
nil
;
}
]
timeout
@H_502_87@:
60
@H_502_87@*
60
onScheduler
@H_502_87@:
[
RACScheduler
mainThreadScheduler
]
]
subscribeError
@H_502_87@:
@H_502_87@^
(
NSError
*error
)
{
NSLog
(
@"等了你一个小时了,你还没来,我走了"
)
;
}
]
;
|
重试
成功之前可能需要数百次失败。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.159
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.159
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.159
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.159
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.160
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.160
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.161
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.162
Test
[
2411
@H_502_87@:
77080
]
我失败了
.
.
.
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.162
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.163
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.163
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.163
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.164
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.164
Test
[
2411
@H_502_87@:
77080
]
我失败了
2015
@H_502_87@-
08
@H_502_87@-
16
21
@H_502_87@:
59
@H_502_87@:
07.164
Test
[
2411
@H_502_87@:
77080
]
我失败了
|
节流
不好意思,这里一秒钟只能通过一个人。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[
[
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)
(
1
@H_502_87@*
NSEC_PER_SEC
)
)
,
dispatch_get_main_queue
(
)
,
@H_502_87@^
{
}
)
;
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)
(
2
@H_502_87@*
NSEC_PER_SEC
)
)
,
@H_502_87@^
{
}
)
;
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)
(
3
@H_502_87@*
NSEC_PER_SEC
)
)
,
@H_502_87@^
{
}
)
;
return
nil
;
NSLog
(
@"%@通过了"
,
x
)
;
}
]
;
|
1
2
3
4
|
2015
@H_502_87@-
08
@H_502_87@-
16
22
@H_502_87@:
08
@H_502_87@:
45.677
Test
[
2618
@H_502_87@:
83764
]
旅客
A
2015
@H_502_87@-
08
@H_502_87@-
16
22
@H_502_87@:
08
@H_502_87@:
46.737
Test
[
2618
@H_502_87@:
83764
]
旅客
B
|
条件
直到世界的尽头才能把我们
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[
[
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
[
[
RACSignal
interval
@H_502_87@:
1
onScheduler
@H_502_87@:
[
RACScheduler
mainThreadScheduler
]
]
subscribeNext
@H_502_87@:
@H_502_87@^
(
id
x
)
{
}
]
;
return
nil
;
}
]
takeUntil
@H_502_87@:
[
RACSignal
createSignal
@H_502_87@:
@H_502_87@^
RACDisposable
@H_502_87@*
(
id
<RACSubscriber>
subscriber
)
{
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)
(
5
@H_502_87@*
NSEC_PER_SEC
)
)
,
@H_502_87@^
{
NSLog
(
@"世界的尽头到了"
)
;
}
)
;
return
nil
;
NSLog
(
@"%@"
,
x
)
;
}
]
;
|
1
2
3
4
5
6
|
2015
@H_502_87@-
08
@H_502_87@-
16
22
@H_502_87@:
17
@H_502_87@:
22.648
Test
[
2766
@H_502_87@:
88737
]
直到世界的尽头才能把我们分开
2015
@H_502_87@-
08
@H_502_87@-
16
22
@H_502_87@:
17
@H_502_87@:
23.648
Test
[
2766
@H_502_87@:
88737
]
直到世界的尽头才能把我们分开
2015
@H_502_87@-
08
@H_502_87@-
16
22
@H_502_87@:
17
@H_502_87@:
24.645
Test
[
2766
@H_502_87@:
88737
]
直到世界的尽头才能把我们分开
2015
@H_502_87@-
08
@H_502_87@-
16
22
@H_502_87@:
17
@H_502_87@:
25.648
Test
[
2766
@H_502_87@:
88737
]
直到世界的尽头才能把我们分开
|
完事
ReactiveCocoa是如此优雅,一旦使用,根本停不下来,上面也只是它的一角冰山,但愿我能挑起你的兴趣。