Skip to content

mathewreny/MRChan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MRChan

Objective-c implementation of Golang channels.

Read MRChan.h before the examples. It's well documented and easy to follow!

How to create a channel.

MRChan *channel  = [[MRChan alloc] init];           // unbuffered channel.
MRChan *bchannel = [[MRChan alloc] initWithSize:5]; // buffered channel

Sending/receiving to/from a channel blocks (waits) until the action can occur.

NSNumber *rec;
[bchannel send:@1];      // Buffered channels don't wait to send unless full.
[bchannel receive:&rec]; //    ""       ""      ""   ""  "" receive ""  empty
XCTAssert(rec.intValue == 1);
// Unbuffered channels must send/receive through different coroutines.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    sleep(10); // emphasize the ease of using channels
    [channel send:@2];
});
[channel receive:&rec];
XCTAssert(received.intValue == 2);

The select method randomly tests every SelectCase until one is ready.

Example: Random number generator.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    SelectCase send0 = [channel caseSend:@0 block:^{ NSLog(@"Sent 0");}];
    SelectCase send1 = [channel caseSend:@1 block:nil];
    while (1) // Begin randomally sending 1s and 0s to the channel.
        [MRChan select:send0, send1, nil];  // need to terminate the list with nil.
});
// create 1000 random numbers.
uint *numbers = calloc(10000, sizeof(uint));
for (int i = 0; i < 10000; i++)
{
    for (int j = 0; j < 32; j++)
    {
        [channel receive:&rec];
        numbers[i] = (numbers[i] << 1) | rec.intValue;
    }
}

Select statements can intermix receive and send cases.

Example: Quit channel test.

__block BOOL quit = false;
MRChan *chan = [[MRChan alloc] initWithSize:3]; // Buffered channel of size 3.
MRChan *quitChan = [[MRChan alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    sleep(10);
    [quitChan send:@1];
});
SelectCase receiveStuff = [chan caseReceive:^(NSString *str){ NSLog(@"Received string %@", str);}];
SelectCase sendStuff = [chan caseSend:@"Hello" block:nil];
SelectCase quitCase = [quitChan caseReceive:^(NSNumber *q){ quit = [q boolValue];}];
while(!quit) 
{
    [MRChan select:receiveStuff, sendStuff, quitCase, nil];
}

About

Objective-c Implementation of Golang Channels and Select!

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors