Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get hold of the currently executing NSOperation?

Is there an equivalent to [NSOperationQueue currentQueue] or [NSThread currentThread] for NSOperation?

I have a fairly complex domain model where the heavy processing happens quite deep down in the call stack. In order to timely cancel an operation I would need to pass the NSOperation as a parameter to every method until I get to the point where I want to interrupt a longer running loop. Using threads I could use [[NSThread currentThread] isCancelled] so it would seem convenient if there is an equivalent for NSOperation, unfortunately there is only the seemingly useless [NSOperationQueue currentQueue].

like image 536
Jon Tirsen Avatar asked Sep 07 '11 15:09

Jon Tirsen


People also ask

How do I cancel NSOperation?

you use cancel , and test whether self (the NSOperation ) has been cancelled during execution.

What is NSOperation and Nsoperationqueue in IOS?

An operation queue invokes its queued NSOperation objects based on their priority and readiness. After you add an operation to a queue, it remains in the queue until the operation finishes its task. You can't directly remove an operation from a queue after you add it. Note.

What are NS operations?

An abstract class that represents the code and data associated with a single task.

What is the difference between GCD and Nsoperationqueue in IOS?

Grand Central Dispatch is a low-level C API that interacts directly with Unix level of the system. NSOperation is an Objective-C API and that brings some overhead with it. Instances of NSOperation need to be allocated before they can be used and deallocated when they are no longer needed.


2 Answers

Came up with an extension in swift that returns the running operations

extension NSOperationQueue {
    public var runningOperations: [NSOperation] {
        return operations.filter {$0.executing && !$0.finished && !$0.cancelled}
    }
}

You can then pick up the first one

if let operation = aQueue.runningOperations.first {}
like image 112
Arsonik Avatar answered Sep 27 '22 22:09

Arsonik


No, there's no method to find the currently executing operation.

Two ways to solve your problem:

  1. Operations are objects. If you need object A to talk to object B, you'll need to arrange for A to have a reference to B. There are lots of ways to do that. One way is to pass the operation along to each object that needs to know about it. Another is to use delegation. A third is to make the operation part of some larger "context" that's passed along to each method or function. If you find that you need to pass a reference from one object through several others just to get it to the object that will finally use it, that's a clue that you should think about rearranging your code.

  2. Have the "heavy lifting" method return some value that gets passed up the call chain. You don't necessarily need the heavy lifting method to call [currentOperation cancel] to accomplish your goal. In fact, it would be better to have it return some value that the operation will understand to mean "work is done, stop now" because it can check that return value and exit immediately rather than having to call -isCancelled once in a while to find out whether it has been cancelled.

like image 27
Caleb Avatar answered Sep 27 '22 23:09

Caleb