๊ฐ๋ณ ๊ฐ๊ฒฉ์ผ๋ก ๋ฐ๋ณต๋๋ ์ ํธ๋ฅผ ์ฌ์ฉํ๋ ํด๋์ค์ PoC๊ฐ ์์ต๋๋ค.
// Repeat.h
#import <Foundation/Foundation.h>
<strong i="6">@interface</strong> Repeat : NSObject
- (instancetype)initWithInterval:(NSInteger)interval;
<strong i="7">@property</strong> (assign, nonatomic) NSInteger interval;
<strong i="8">@property</strong> (readonly, nonatomic) RACSubject *dataSubject;
<strong i="9">@end</strong>
// Repeat.m
#import <ReactiveCocoa/ReactiveCocoa.h>
#import "Repeat.h"
<strong i="12">@interface</strong> Repeat ()
<strong i="13">@property</strong> (readwrite, strong, nonatomic) RACSubject *dataSubject;
<strong i="14">@property</strong> (readwrite, strong, nonatomic) RACSignal *dataSignal;
<strong i="15">@end</strong>
<strong i="16">@implementation</strong> Repeat
- (instancetype)initWithInterval:(NSInteger)interval
{
self = [super init];
if (self) {
self.dataSubject = [RACSubject subject];
self.dataSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
static int i = 0;
[subscriber sendNext:@(i++)];
return nil;
}];
self.interval = interval;
[RACObserve(self, interval) subscribeNext:^(id x) {
RACSignal *limit = [RACObserve(self, interval) skip:1];
RACSignal *repeater = [[RACSignal interval:[x integerValue]
onScheduler:[RACScheduler mainThreadScheduler]]
takeUntil:limit];
RACSignal *tickSignal = [repeater doCompleted:^{
NSLog(@"interval changed to: %lu", self.interval);
}];
[[tickSignal flattenMap:^RACStream *(id value) { // *
return self.dataSignal;
}] subscribeNext:^(id x) {
[self.dataSubject sendNext:x];
}];
}];
}
return self;
}
<strong i="17">@end</strong>
์ฌ์ฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Repeat *repeater = [[Repeat alloc] initWithInterval:3];
[repeater.dataSubject subscribeNext:^(id x) {
// do something with x
}];
...
// somehwere else in the code
repeater.interval = 5;
์ด๋ฅผ ํตํด ๊ตฌ๋
์ ์ ์งํ๊ณ ์ ํธ ๊ฐ ์ ๋ฌ ๊ฐ๊ฒฉ ๋ง ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์๋น์๊ฐ ์ ํธ๋ณด๋ค๋ ์ฃผ์ ๋ฅผ ์ค์ ๋ก ๊ตฌ๋
ํด์ผํ๋ ๋ถ๋ถ์ด ๊ฑฑ์ ๋ฉ๋๋ค. ๋๋ ์ด๊ฒ์ด ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค๊ฐ ์๋๋ผ๋ ๊ฒ์ ์ดํดํ๊ณ ๊ฐ์ด๋ ๋ผ์ธ์ ์ค์ ๋ก ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์ฃผ์ ๋ฅผ ํผํ๋๋ก ๊ถ์ฅํฉ๋๋ค. ๊ณต์ฉ ์ธํฐํ์ด์ค์ dataSignal
๋ฅผ ๋
ธ์ถํ๊ณ // *
๋ก ํ์๋ ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ์ด ๊ต์ฒดํด ๋ณด์์ต๋๋ค.
[tickSignal subscribeNext:^(id x) {
[self.dataSignal replayLast];
}];
๊ทธ๋ฌ๋ ์ด๊ฒ์ ์ ํ ์๋ํ์ง ์์ผ๋ฉฐ ์ด๊ธฐ ๊ฐ๋ง ์ ์ก๋ฉ๋๋ค. ๋ค๋ฅธ ์ฌ๋์ด ๋ด๊ฐ ์ฌ๊ธฐ์ ๋ฌ์ฑํ๋ ค๋ ๊ฒ์ ๊ตฌํํ๋ ค๊ณ ์๋ ํ์ต๋๊น? RAC๊ฐ์ด ์์ ์ ์ํ ํ ์ ์๋ค๊ณ ํ์ ํ๊ณ ๋ด PoC๋ ํฌ๊ฒ ๊ฐ์ ํ ์์๋ ์ถ์ ํ ์๋ผ ์ค๋ฆฌ์ ๋๋ค.
์์ ์ ์ฌ๊ธฐ์์ ์ฐพ์ ์ ์์ต๋๋ค : https://gist.github.com/eimantas/51d9dfc81136f340a829
์ ๋ฐ์ดํธ : @jspahrsummers๋ฅผ ๊ธฐ๋ฐ์ผ๋ก stackoverflow์ ๋ํ ์ง๋ฌธ์ ๋ํ ๋ต๋ณ : http://stackoverflow.com/questions/15075075/when-to-use-racreplaysubject-vs-racmulticastconnection
RACMulticastConnection์ด ๋์ผํ ์์
์ ์ํํ๋ ๊ฒ ๊ฐ์ต๋๋ค. RACSubject
์ RACSignal
๋ก ๋
ธ์ถํ๋ฏ๋ก ๋ค์ ์์
์ ์ํํด์ผํฉ๋๊น?
ํ์ด๋จธ๊ฐ ์ค์ ๋ก ์ข
๋ฃ๋์ง ์๋ ๊ฒฝ์ฐ concat:[RACSignal delay:N]
ํ๊ณ ๊ทธ ํ์ concat:[RACSignal defer:^{}]
์์ ์์ฒด ํธ์ถํ๋ ์ฌ๊ท ๋ฉ์๋๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
์ฆ, ๋ฌดํํ ์ผ๋ จ์ ์์ ์ ์ ํธ ์ฌ์ด์ N ์ด์ ์ง์ฐ์ ์ฝ์ ํฉ๋๋ค.
ํ์ด๋จธ๋ ์ฌ์ฉ์์ ๋ช ๋ น์ผ๋ก ์ข ๋ฃ ํ ์ ์์ต๋๋ค. ์ฌ๊ท์ ๊ด๋ จํ์ฌ ๋ด CS๊ฐ ๋ น์ฌ ์ ์์ง๋ง ๊ฒฐ๊ตญ ์คํ ํ๋ ์ ์ค๋ฒํ๋ก๊ฐ ๋ฐ์ํ์ง ์์๊น์?
@eimantas ์๋์, ์ง์ฐ์ด ๋ ๊ธฐ์ ์ด์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. RAC๋ ํ๋ ์์ ๋ ๋ ์ง์ฐ์ด ๊ฒฝ๊ณผ ํ ํ ๋์ค์ ์ฝ๋๋ก ๋์๊ฐ๋๋ค.
์ฃ์ก ํฉ๋๋ค๋ง, ์ฌ์ ํ ๊ทํ์ ์์ด๋์ด๋ฅผ ์ป์ง ๋ชปํ์ต๋๋ค. (๊ตฌ์ฒด์ ์ผ๋ก concat:[RACSignal delay:N]
์ ํํด์ผํฉ๋๊น?
- (RACSignal *)doStuffRepeatedly {
return [[[RACSignal
defer:^{
// Do some stuff here
return [RACSignal empty];
}]
// Wait 5 seconds
concat:[RACSignal delay:5]]
then:^{
// Do more stuff
return [self doStuffRepeatedly];
}];
}
ํ๋์ด ์์ด์ ๋ซ์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ