Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I am not an expert in NSOperation or NSOperationQueues but I think below code is a bit better although I think it has some caveats still. Probably enough for some purposes but is not a general solution for concurrency:</p> <pre><code>- (NSOperation *)executeBlock:(void (^)(void))block inQueue:(NSOperationQueue *)queue completion:(void (^)(BOOL finished))completion { NSOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:block]; NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{ completion(blockOperation.isFinished); }]; [completionOperation addDependency:blockOperation]; [[NSOperationQueue currentQueue] addOperation:completionOperation]; [queue addOperation:blockOperation]; return blockOperation; } </code></pre> <p>Now lets use it:</p> <pre><code>- (void)tryIt { // Create and configure the queue to enqueue your operations backgroundOperationQueue = [[NSOperationQueue alloc] init]; // Prepare needed data to use in the operation NSMutableString *string = [NSMutableString stringWithString:@"tea"]; NSString *otherString = @"for"; // Create and enqueue an operation using the previous method NSOperation *operation = [self executeBlock:^{ NSString *yetAnother = @"two"; [string appendFormat:@" %@ %@", otherString, yetAnother]; } inQueue:backgroundOperationQueue completion:^(BOOL finished) { // this logs "tea for two" NSLog(@"%@", string); }]; // Keep the operation for later uses // Later uses include cancellation ... [operation cancel]; } </code></pre> <p>Some answers to your questions:</p> <ol> <li><p><strong>Cancelation</strong>. Usually you subclass NSOperation so you can check <code>self.isCancelled</code> and return earlier. See <a href="https://stackoverflow.com/questions/3859631/subclassing-nsoperation-to-be-concurrent-and-cancellable">this thread</a>, it is a good example. In current example you cannot check if the operation has being cancelled from the block you are supplying to make an <code>NSBlockOperation</code> because at that time there is no such an operation yet. Cancelling <code>NSBlockOperation</code>s while the block is being invoked is apparently possible but <a href="https://stackoverflow.com/questions/8113268/how-to-cancel-nsblockoperation">cumbersome</a>. <code>NSBlockOperation</code>s are for specific easy cases. If you need cancellation you are better subclassing <code>NSOperation</code> :)</p></li> <li><p>I don't see a problem here. Although note two things. a)I changed the method do to run the completion block in current queue b)a queue is required as a parameter. As @Mike Weller said, you should better supply <code>background queue</code> so you don't need to create one per each operation and can choose what queue to use to run your stuff :)</p></li> <li><p>I think yes, you should make <code>string</code> <code>atomic</code>. One thing you should not forget is that if you supply several operations to the queue they might not run in that order (necessarily) so you could end up with a very strange message in your <code>string</code>. If you need to run one operation at a time serially you can do: <code>[backgroundOperation setMaxConcurrentOperationCount:1];</code> before start enqueuing your operations. There is a reading-worthy note in the <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html" rel="nofollow noreferrer">docs</a> though:</p> <blockquote> <p><strong>Additional Operation Queue Behaviors</strong> An operation queue executes its queued operation objects based on their priority and readiness. If all of the queued operation objects have the same priority and are ready to execute when they are put in the queue—that is, their isReady method returns YES—they are executed in the order in which they were submitted to the queue. For a queue whose maximum number of concurrent operations is set to 1, this equates to a serial queue. However, you should never rely on the serial execution of operation objects. Changes in the readiness of an operation can change the resulting execution order.</p> </blockquote></li> <li><p>I think after reading these lines you know :)</p></li> </ol>
    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. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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