Skip to content

Instantly share code, notes, and snippets.

@couchdeveloper
Created May 10, 2013 18:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save couchdeveloper/5556360 to your computer and use it in GitHub Desktop.
Save couchdeveloper/5556360 to your computer and use it in GitHub Desktop.
Play around with NSOperationQueue and NSOperation.
#import <Foundation/Foundation.h>
#include <dispatch/dispatch.h>
@interface Operation : NSOperation
@property (nonatomic, readwrite) BOOL isExecuting;
@property (nonatomic, readwrite) BOOL isFinished;
@property (nonatomic, readwrite) BOOL terminating;
@end
@implementation Operation {
NSInteger _workCount;
dispatch_queue_t _workerQueue;
}
@synthesize isExecuting = _isExecuting; // explicitly implemented
@synthesize isFinished = _isFinished; // explicitly implemented
- (id)initWithWorkCount:(NSInteger)count workerQueue:(dispatch_queue_t)workerQueue
{
NSParameterAssert(workerQueue);
self = [super init];
if (self) {
_workCount = count;
dispatch_retain(workerQueue);
_workerQueue = workerQueue;
}
return self;
}
- (void) dealloc {
dispatch_release(_workerQueue);
}
- (void) doWork
{
if (_workCount == 0) {
[self terminate];
return;
}
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, _workerQueue, ^(void){
printf("%p: %ld\n", self, (long)_workCount);
_workCount--;
[self doWork];
});
}
- (void) start
{
if (self.isCancelled || self.isFinished || self.isExecuting) {
return;
}
self.isExecuting = YES;
[self doWork];
}
- (BOOL) isCancelled {
return [super isCancelled];
}
- (void) cancel {
[super cancel];
}
- (BOOL) isExecuting {
return _isExecuting;
}
- (void) setIsExecuting:(BOOL)isExecuting {
if (_isExecuting != isExecuting) {
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = isExecuting;
[self didChangeValueForKey:@"isExecuting"];
}
}
- (BOOL) isFinished {
return _isFinished;
}
- (void) setIsFinished:(BOOL)isFinished {
if (_isFinished != isFinished) {
[self willChangeValueForKey:@"isFinished"];
_isFinished = isFinished;
[self didChangeValueForKey:@"isFinished"];
}
}
- (void) terminate {
self.isFinished = YES;
self.isExecuting = NO;
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
dispatch_queue_t workerQueue = dispatch_queue_create("worker queue", 0);
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1000;
for (int i = 0; i < 100; ++i) {
Operation* op = [[Operation alloc] initWithWorkCount:10 workerQueue:workerQueue];
[queue addOperation:op];
}
NSLog(@"Start");
[queue waitUntilAllOperationsAreFinished];
NSLog(@"Finished");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment