问题
I've created a GCD queue like this:
dispatch_queue_t q = dispatch_queue_create("com.testcompany.myqueue", NULL);
When I dispatch tasks to that queue, it is way slower than simply executing the task on the main thread.
dispatch_async(q, ^(void) {
[self performHeavyCalculationAndUpdateUI];
});
My suspicion is that the queue has a very low priority by default. How can I change the priority of this queue? Or is there something else I must do?
回答1:
If you're doing UIKit stuff, in your block that's running on the secondary queue, dispatch the UI updates back to the main queue from within the secondary queue via:
dispatch_async(q, ^(void) {
[self performHeavyCalculationAndUpdateUI];
dispatch_async(dispatch_get_main_queue(), ^{
// do my ui update
});
});
Just dispatch the few lines that actually update the UI back to the main queue and you'll see it's not a matter of queue priorities, but rather just making sure that UI updates happen in main queue.
回答2:
Dispatch queues don't have a priority you can change.
You can change the target queue of your serial queues using the dispatch_set_target_queue
functions and use the DISPATCH_QUEUE_PRIORITY_HIGH
global queue. This just ensures that it will be scheduled before any other blocks enqueued on the queues with the default or low priority. Once your block starts executing it will not run faster or slower no matter what queue it was scheduled on.
Your problem most likely is the updating of your GUI, see Robert Ryans answer.
回答3:
I think you're missing the point of asynchronous activities. And @RobertRyan's comment about UI updates not showing up quickly if performed on secondary queues is wrong. All UI updates need to be performed on the main queue. Period.
But back to GCD and the async queue. @Sven is right that you can't change the priority of the dispatch queues. Queues in GCD work in a FIFO (First In First Out) fashion, so the order you queue them up is the order they get performed in. This is part of why using GCD is thread-safe; you're guaranteed you won't run into any issues because of this FIFO queue priority. The second thing to understand is that when you dispatch_async a queue, the OS provides no guarantee of when that queue will be processed. It's a set-it-and-forget it type of process. If you need to know when the queue is done processing, you need to set up a completion block handler (you'll notice many of Apple's Frameworks have begun to implement this) to be notified of that. This is why Apple suggests nesting a dispatch_async call within your first dispatch_async call and requesting the main thread for UI updates. So, your code would look something like this:
dispatch_async(q, ^{
[self performHeavyCalculations];
dispatch_async(dispatch_get_main_queue, ^{
// some UI updates
});
});
Because of how GCD enqueues and dequeues, dispatching your UI updates asyncronously back to the main queue will allow for UI updates to occur without a perceptible delay to the user. If your UI updates depend on the result of performHeavyCalculations, you'll need to set up a completion handler or delegation scheme to notify the main queue of when this is complete so that the updates can occur. If the lag between the calculations and the update is too long, you may need to look into what you're doing in the calculations method that is taking so long.
来源:https://stackoverflow.com/questions/9965018/how-to-modify-the-priority-of-a-custom-gcd-queue