6

How to stop receiving new name after some event?

[RACObserve(self, username) subscribeNext:^(NSString *newName) {
    if ([newName isEqualToString:@"SomeString"])
    {
       //Do not observe any more
    }
}];

P.S. Sorry for obvious question, but I can't find answer

serj
  • 301
  • 4
  • 10

2 Answers2

11

You can use method 'dispose' of RACDisposable object which be returned from 'subscribeNext'.

__block RACDisposable *handler = [RACObserve(self, username) subscribeNext:^(NSString *newName) {
    if ([newName isEqualToString:@"SomeString"]) {
        //Do not observe any more
        [handler dispose]
    }
}];
KM Gorbunov
  • 111
  • 6
9

It's important to think about things a little differently in ReactiveCocoa: you don't want to "remove" an observer, you want to create a signal that completes when something happens.

You can use takeUntilBlock: to derive a signal that will stop sending values after a certain time:

[[RACObserve(self, username) takeUntilBlock:^(NSString *name) {
    return [name isEqualToString:@"something"];
}] subscribeNext:^(NSString *name) {
    NSLog(@"%@", name);
}];

But that will not send a next for the string @"something", only the names before it. If that's desired, you could append it:

NSString *sentinel = @"something";
[[[RACObserve(self, username) takeUntilBlock:^(NSString *name) {
    return [name isEqualToString:sentinel];
}] concat:[RACSignal return:sentinel]] subscribeNext:^(NSString *name) {
    NSLog(@"%@", name);
}];

It's not very elegant, but you could make a takeUntilBlockInclusive helper that would get you this behavior, and hide the grossness in there.

Ian Henry
  • 22,255
  • 4
  • 50
  • 61