Skip to content

Instantly share code, notes, and snippets.

@janodev
Created June 24, 2012 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janodev/2983678 to your computer and use it in GitHub Desktop.
Save janodev/2983678 to your computer and use it in GitHub Desktop.
Asynchronous testing. Runs in CodeRunner.
// TEST ASYNCHRONOUS CODE
// Runs in Code Runner
#import <Foundation/Foundation.h>
@interface Test : NSObject
-(void)test1BooleanFlag;
-(void)test2BooleanFlagAndTimeLimit;
-(void)test3Semaphore;
@end
@implementation Test
// After 3 seconds run a task that takes 1 second to complete. Once completed,
// the task changes a boolean flag. Loop processing events for 1 second until
// the global boolean flag changes.
-(void)test1BooleanFlag
{
// use __block so you read write or use a global variable
__block bool finished = false;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
dispatch_time_t threeSeconds = dispatch_time(DISPATCH_TIME_NOW, 3LL * NSEC_PER_SEC);
dispatch_after(threeSeconds, queue, ^{
sleep(1);
finished = true;
});
while (!finished) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
}
// Same thing as before, but the loop has a time limit of 2 seconds, so the test fails.
-(void)test2BooleanFlagAndTimeLimit
{
__block bool finished = false;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3LL * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
NSLog(@"Task running...");
sleep(1);
finished = true;
NSLog(@"Task done.");
});
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:2];
while (!finished && [timeout timeIntervalSinceNow]>0) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
if (!finished) NSLog(@"test2BooleanFlagAndTimeLimit failed");
}
// Same thing but
-(void)test3Semaphore {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// signal the semaphore after 3 seconds using a global queue
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3LL * NSEC_PER_SEC), queue, ^{
sleep(1);
dispatch_semaphore_signal(semaphore);
});
// Wait forever for the semaphore to be available. If the semaphore is not
// signaled we are stuck. Note that this wait blocks the main queue, but
// the task is still running on the global queue.
// dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// wait with a time limit
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, 5LL*NSEC_PER_SEC);
if (dispatch_semaphore_wait(semaphore, timeout)==0) {
NSLog(@"success, semaphore signaled in time");
} else {
NSLog(@"failure, semaphore signaled in time");
}
dispatch_release(semaphore);
}
// Runs the task in a queue and group. Waits with time limit.
-(void)test4Group
{
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
// dispatch work to the given group and queue
dispatch_group_async(group,queue,^{
sleep(1);
});
// Dispatch a task to the queue when the blocks on the group are finished.
dispatch_group_notify(group, queue, ^{
dispatch_release(group);
});
// wait two seconds for the group to finish
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, 2LL*NSEC_PER_SEC);
if (dispatch_group_wait(group, timeout)==0) {
NSLog(@"success, dispatch group completed in time");
} else {
NSLog(@"failure, dispatch group did not complete in time");
}
}
@end
int main(int argc, char *argv[])
{
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
Test *test = [Test new];
//[test test1BooleanFlag];
//[test test2BooleanFlagAndTimeLimit];
//[test test3Semaphore];
[test test4Group];
[p release];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment