├── .gitignore ├── IISerialAsyncOperationQueue.podspec ├── IISerialAsyncOperationQueue ├── IISerialAsyncOperationQueue.h └── IISerialAsyncOperationQueue.m ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # xcode noise 2 | build/* 3 | *.pbxuser 4 | *.mode1v3 5 | *.xcworkspace 6 | xcuserdata 7 | project.xcworkspace/* 8 | xcuserdata/* 9 | 10 | # osx noise 11 | .DS_Store 12 | profile -------------------------------------------------------------------------------- /IISerialAsyncOperationQueue.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'IISerialAsyncOperationQueue' 3 | s.version = '1.0' 4 | s.summary = 'A serial queue supporting async operations. The next operation starts only after the previous one completes.' 5 | s.homepage = 'https://github.com/Inferis/IISerialAsyncOperationQueue' 6 | s.social_media_url = 'https://twitter.com/inferis' 7 | s.license = { :type => 'MIT', :file => 'LICENSE' } 8 | s.author = { 'Tom Adriaenssen' => 'http://inferis.org/' } 9 | s.source = { :git => 'https://github.com/Inferis/IISerialAsyncOperationQueue.git', 10 | :tag => '1.0'} 11 | s.source_files = 'IISerialAsyncOperationQueue/*.{h,m}' 12 | s.requires_arc = true 13 | end 14 | -------------------------------------------------------------------------------- /IISerialAsyncOperationQueue/IISerialAsyncOperationQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // IISerialAsyncOperationQueue.h 3 | // Copyright (c) 2014 Tom Adriaenssen. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @protocol IISerialAsyncOperation 9 | 10 | - (void)complete; 11 | 12 | @end 13 | 14 | 15 | @interface IISerialAsyncOperationQueue : NSObject 16 | 17 | - (void)addOperation:(void(^)(id completion))action; 18 | 19 | - (void)setOperation:(void(^)(id completion))action; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /IISerialAsyncOperationQueue/IISerialAsyncOperationQueue.m: -------------------------------------------------------------------------------- 1 | // 2 | // SingleOperation.m 3 | // Drash2 4 | // 5 | // Created by Tom Adriaenssen on 16/08/13. 6 | // Copyright (c) 2013 Tom Adriaenssen. All rights reserved. 7 | // 8 | 9 | #import "IISerialAsyncOperationQueue.h" 10 | 11 | @interface IISerialAsyncOperation : NSObject 12 | 13 | - (void)wait; 14 | 15 | @end 16 | 17 | 18 | 19 | @implementation IISerialAsyncOperationQueue { 20 | NSOperationQueue* _queue; 21 | dispatch_queue_t _dqueue; 22 | } 23 | 24 | - (id)init { 25 | if ((self = [super init])) { 26 | _queue = [NSOperationQueue new]; 27 | _queue.maxConcurrentOperationCount = 1; 28 | _dqueue = dispatch_queue_create(NULL, 0); 29 | } 30 | return self; 31 | } 32 | 33 | - (void)addOperation:(void(^)(id completion))action 34 | { 35 | [self addOperation:action cancelAll:NO]; 36 | } 37 | 38 | - (void)setOperation:(void(^)(id completion))action 39 | { 40 | [self addOperation:action cancelAll:YES]; 41 | } 42 | 43 | - (void)addOperation:(void(^)(id completion))action cancelAll:(BOOL)cancelAll 44 | { 45 | if (!action) 46 | return; 47 | 48 | __block NSOperation* operation; 49 | operation = [NSBlockOperation blockOperationWithBlock:^{ 50 | if ([operation isCancelled]) 51 | return; 52 | 53 | IISerialAsyncOperation* completion = [IISerialAsyncOperation new]; 54 | dispatch_async(_dqueue, ^{ 55 | action(completion); 56 | }); 57 | [completion wait]; 58 | }]; 59 | 60 | if (cancelAll) [_queue cancelAllOperations]; 61 | [_queue addOperation:operation]; 62 | } 63 | 64 | @end 65 | 66 | 67 | 68 | @implementation IISerialAsyncOperation { 69 | dispatch_semaphore_t _semaphore; 70 | } 71 | 72 | - (void)complete { 73 | if (_semaphore) { 74 | dispatch_semaphore_signal(_semaphore); 75 | } 76 | } 77 | 78 | - (void)wait { 79 | [self wait:-1]; 80 | } 81 | 82 | - (void)wait:(NSTimeInterval)timeout { 83 | dispatch_time_t time = DISPATCH_TIME_NOW; 84 | if (timeout < 0) { 85 | time = DISPATCH_TIME_FOREVER; 86 | } 87 | else if (timeout > 0) { 88 | time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)); 89 | } 90 | 91 | _semaphore = dispatch_semaphore_create(0); 92 | dispatch_semaphore_wait(_semaphore, time); 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Tom Adriaenssen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IISerialAsyncOperationQueue 2 | 3 | A serial queue supporting async operations. The next operation starts only after the previous one completes. 4 | 5 | This is the same as simple serial `NSOperationQueue`, but this one is geared towards async operations which is a bit harder to do with a plain old NSOperationQueue. 6 | 7 | ## Usage 8 | 9 | Using this component is pretty simple. You create an instance and then add operations to it. 10 | 11 | There's two actions possible: 12 | 13 | * `setOperation:`: adds the operation to the queue but also removes all pending operations. The currently executing operation (if any) will continue until it is complete, after that the added operation is run. This call effectively clears all previously added operations replacing them with the new operation. 14 | * `addOperation:`: adds the operation to the queue and leave all other pending operations be. All operations will be executed in the order they were passed. The added operation will only be run after all other queued operations are completed. 15 | 16 | Either way, if no operations are pending, the operation will be run immediately. 17 | 18 | For example: 19 | 20 | ``` 21 | IISerialAsyncOperationQueue *queue = [IISerialAsyncOperationQueue new]; 22 | 23 | [queue addOperation:^(id operation) { 24 | [do somethingAsync:^{ 25 | [operation finish]; 26 | }]; 27 | }]; 28 | ``` 29 | 30 | ## License 31 | 32 | **IISerialOperationQueue** is published under the MIT License. 33 | 34 | See [LICENSE](LICENSE) for the full license. --------------------------------------------------------------------------------