Skip to content

Instantly share code, notes, and snippets.

@jaredru
Last active June 30, 2017 02:09
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaredru/5540a15c5a1bdcc31787 to your computer and use it in GitHub Desktop.
Save jaredru/5540a15c5a1bdcc31787 to your computer and use it in GitHub Desktop.
A ReactiveCocoa 2.x `-shareWhileActive` backport
- (RACSignal *)shareWhileActive {
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
lock.name = @"com.github.ReactiveCocoa.shareWhileActive";
// These should only be used while `lock` is held.
__block NSUInteger subscriberCount = 0;
__block RACDisposable *underlyingDisposable = nil;
__block RACReplaySubject *inflightSubscription = nil;
return [[RACSignal
createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
__block RACSignal* signal = nil;
__block RACDisposable* disposable = nil;
[lock lock];
@onExit {
[lock unlock];
disposable = [signal subscribe:subscriber];
};
if (subscriberCount++ == 0) {
// We're the first subscriber, so create the underlying
// subscription.
inflightSubscription = [RACReplaySubject subject];
underlyingDisposable = [self subscribe:inflightSubscription];
}
signal = inflightSubscription;
return [RACDisposable disposableWithBlock:^{
[disposable dispose];
[lock lock];
@onExit {
[lock unlock];
};
NSCAssert(subscriberCount > 0, @"Mismatched decrement of subscriberCount (%lu)", (unsigned long)subscriberCount);
if (--subscriberCount == 0) {
// We're the last subscriber, so dispose of the
// underlying subscription.
[underlyingDisposable dispose];
underlyingDisposable = nil;
// Also, release the inflightSubscription, since
// we won't need its stored values any longer.
inflightSubscription = nil;
}
}];
}]
setNameWithFormat:@"[%@] -shareWhileActive", self.name];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment