0

I have multiple functions which should be happening in order. And function1 and function3 run in back thread. Their functions are findObjectsInBackgroundWithBlock. Function 2 can be happening on main thread or on back thread, but it should run after function 1 and function 3 should happen right after function2. I got to know about NSOperation and NSOperationQueue but I'm not sure how to really use it. Based on what I researched, I can only make class to subclass NSOperation. Is this correct? I would like to make each functions to be under NSOpeation. Below is the way I think to be correct. Is this right way to approach? And is it correct to put function1() inside of NSOperation like below? Lastly, does it affect NSOperationQueue when some functions are happening in back thread like function 1 & 3 ? Thank you

var operationQueue = NSOperationQueue()
let operation1 : NSOperation = NSOperation(function1())
let operation2 : NSOperation = NSOperation(function2())
let operation3 : NSOperation = NSOperation(function3())

operation2.addDependency(operation1)
operation3.addDependency(operation2)

operationQueue.addOperation(operation1)
operationQueue.addOperation(operation2)
operationQueue.addOperation(operation3)        

func function1 () {
//do something and save data in this class's property
}

func function2 () {
//get data from class's property(data from function1) and do something
//save the result in class's property
}

func function3 () {
  //get data from class's property(data from function2) and do something
 //save the result in class's property
}
Kahsn
  • 1,045
  • 3
  • 15
  • 25

2 Answers2

2

You can use an NSBlockOperation to wrap a block, like this:

    let operationQueue = NSOperationQueue()

    let operation1 = NSBlockOperation {
        // body of function 1
    }

    let operation2 = NSBlockOperation {
        // or call function 2
    }

    operation2.addDependency(operation1)

    operationQueue.addOperation(operation1)
    operationQueue.addOperation(operation2)

Also, you can directly enqueue blocks on the queue:

    operationQueue.addOperationWithBlock {
        // body of function 3
    }

The drawback is you don't have access to the operation so you can't set up dependencies.

David Koski
  • 965
  • 7
  • 12
  • Thank you! I do not get the part that i cannot set up dependencies when you wrote "addDependency" there. Can you explain a bit more? – Kahsn Jul 27 '15 at 07:07
  • This approach will not work when the three functions, themselves, are asynchronous. – Rob Jul 27 '15 at 11:37
  • 1
    @Kahsn - His point was that if you use `addOperationWithBlock` you cannot use dependencies (because `addOperationWithBlock` creates operation and adds it to the queue, but never returns the `NSOperation` reference that you need for `addDependency`). But if you use the `NSBlockOperation`, it works fine (but only if the functions run synchronously). – Rob Jul 27 '15 at 11:41
2

In order for dependencies to work correctly when your functions are, themselves, performing asynchronous operations, you have to:

  • subclass NSOperation;

  • make sure the asynchronous property returns true; and

  • perform the necessary isExecuting and isFinished KVO.

Also, when implementing asynchronous operations, you also should:

  • implement cancelation logic that does more than just flag the operation as complete, but also stops any request that might be in progress.

For an example of concurrent/asynchronous operations with NSURLSession, see https://stackoverflow.com/a/27022598/1271826. The principles outlined there would apply here, too.

Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044