Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>My project did evolve significantly since I've asked this question.</p> <p>From the structural point of view, I can't say much interesting about asynchronous operations: in my project they are all based on dispatch_async and the most valuable functionality is implemented with intensive usage of blocks (mainly: yielding operations themselves to the blocks they execute, allows to control a flow of these operations).</p> <p>The more interesting thing to note here is the code I currently use for synchronous (or "forced-synchronous") operations - though their usage should be avoided in real apps, they are still applicable in unit tests: one example is a need to straighten the curly asynchronous flow of asynchronous net request to test its result in place, in the context of unit test case. </p> <p>Though I am posting this as an answer to my non-specific question I would still really like to see any authoritative answer about whether my SASyncOperation is good enough for forced-sync operations (in the sense I've described it in this question) or maybe it could be improved more.</p> <p><a href="https://github.com/stanislaw/SACompositeOperations/blob/master/SACompositeOperations/SASyncOperation.m" rel="nofollow">SASyncOperation</a> as it currently written</p> <ul> <li>Does not block main thread if it is run on main thread.</li> <li>Does not produce excessive CPU polling as simple approaches with <em>while(!completed){};</em> do.</li> </ul> <p>This is the most important part of the code:</p> <pre><code>#import "SASyncOperation.h" @interface SASyncOperation () { BOOL _isOnMainThread; dispatch_semaphore_t _semaphore; } @end @implementation SASyncOperation // … - (void)start { _semaphore = dispatch_semaphore_create(0); _operation(self); if (_finished) return; if ((_isOnMainThread = [NSThread isMainThread])) { while (dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_NOW)) { CFRunLoopRunInMode(kCFRunLoopDefaultMode, [[NSDate distantFuture] timeIntervalSinceNow], NO); } } else { dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); } _finished = YES; } - (void)run:(^(void)(SASyncOperation *)block { _operation = [block copy]; [self start]; } - (void)finish { _finished = YES; dispatch_semaphore_signal(_semaphore); if (_isOnMainThread) { dispatch_async(dispatch_get_main_queue(), ^{ CFRunLoopStop(CFRunLoopGetMain()); }); } } // … @end </code></pre> <p>This is how SASyncOperation should be used:</p> <pre><code>SASyncOperation *syncOperation = [[SASyncOperation alloc] init]; [syncOperation run:^(SASyncOperation *so) { doSomeThingMultiQueuedPossiblyMultiblockedAndAsynchronous(^{ soOver = YES; [so finish]; }); }]; // &lt;- (*) // (*) The flow will be stopped at this point waiting when 'so' operation will finish itself </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload