I created an NSOperation subclass to handle some zip archive operations. No matter what, if I override -start
or -main
this block of code always happens:
if ([NSThread isMainThread]) {
NSLog(@"I am in the main thread");
return;
}
Any idea what's going on?
I've tried adding this block:
- (void) start { //also tried overriding main
if ([NSThread isMainThread]) {
NSLog(@"In main thread, trying again");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self start];
});
return;
//hard working code etc...
//cpu intensive zip operations...
}
But this causes a crash, an EXC_BAD_ACCESS
violation pointing at the dispatch_async
line.
Grand Central Dispatch is ideal if you just need to dispatch a block of code to a serial or concurrent queue. If you don't want to go through the hassle of creating an NSOperation subclass for a trivial task, then Grand Central Dispatch is a great alternative.
NSOperationQueue works best when tasks are discrete, synchronous and live in the same thread (eg they are more or less atomic), the queue can be used as basic thread pool though in almost any situation.
NSOperationQueue always executes operations concurrently, while taking dependencies into account. A "non-concurrent" operation requires a separate thread in order to execute concurrently.
A queue that regulates the execution of operations.
No matter what, if I override -start or -main this block of code always happens:
The main operation queue runs on the main thread. From the docs for +[NSOperationQueue mainQueue]
:
The returned queue executes operations on the main thread. The main thread’s run loop controls the execution times of these operations.
So, running in another thread is a matter of what queue you add the operation to, not how you write the operation's code. If you want your operation to run on a different operation queue, you'll need to create a queue of your own using
NSOperationQueue* aQueue = [[NSOperationQueue alloc] init];
You can find an example in Adding Operations to an Operation Queue in the Concurrency Programming Guide.
But this causes a crash, an EXC_BAD_ACCESS violation pointing at the dispatch_async line.
It sounds like -[NSOperation start]
probably isn't re-entrant. Your code effectively executes the same method on two different threads. In fact, look at the docs for -start
, it's obvious that your code won't work:
You can call this method explicitly if you want to execute your operations manually. However, it is a programmer error to call this method on an operation object that is already in an operation queue or to queue the operation after calling this method. Once you add an operation object to a queue, the queue assumes all responsibility for it. [Emphasis added. -Caleb]
In other words, don't do that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With