Last active
December 14, 2015 04:59
-
-
Save jspahrsummers/5032383 to your computer and use it in GitHub Desktop.
An example of emulating an asynchronous pull-driven stream with lazy signals. The idea is that the producer (in this case, a socket) should be throttled to a speed that the consumer (the signal subscribers) can handle – accomplished here by using multiple individual signals which only read data when subscribed to.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface RACSocketReader : NSObject | |
// Sends a RACSignal whenever there's new data ready to be read. Each signal | |
// will send an NSData upon subscription. | |
// | |
// If you only want the NSData objects as fast as possible, simply -concat | |
// this signal to get a eager signal of NSData values. | |
@property (nonatomic, strong, readonly) RACSignal *signalOfDataSignals; | |
- (id)initWithSocketDescriptor:(int)fildes; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface RACSocketReader () { | |
RACSubject *_signalOfDataSignals; | |
} | |
@end | |
@implementation RACSocketReader | |
- (id)initWithSocketDescriptor:(int)fildes { | |
self = [super init]; | |
if (self == nil); | |
// (Set up socket stuff here.) | |
_signalOfDataSignals = [RACSubject subject]; | |
[self sendNextDataSignal]; | |
return self; | |
} | |
// Creates a signal of a single NSData value, which only reads from the socket upon the first | |
// subscription, then sends it on signalOfDataSignals. | |
// | |
// After the first subscription, the next data signal is automatically sent on | |
// signalOfDataSignals as well. | |
- (void)sendNextDataSignal { | |
RACSignal *coldSignal = [RACSignal createSignal:^ id (id<RACSubscriber> subscriber) { | |
// On subscription, we read from the socket, and send that data on | |
// this signal before completing. | |
NSData *data = [self readFromSocket]; | |
[subscriber sendNext:data]; | |
[subscriber sendCompleted]; | |
// But then we also want to prepare the next lazy signal. | |
[self sendNextDataSignal]; | |
return nil; | |
}]; | |
// -replayLazily ensures that the signal only starts when subscribed to, and | |
// only once. | |
[_signalOfDataSignals sendNext:[coldSignal replayLazily]]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@interface RACSocketReader : NSObject
?