Инкапсулируйте каждый запрос на доступ к словарю в объекте NSBlockOperation или NSInvocation, затем добавьте операцию в NSOperationQueue, установив максимальное количество одновременных операций равным 1:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Doing something...");
}];
[queue addOperation:operation];
Если существует согласованный шаблон доступа, например, присущий реализациям, использующим шаблон проектирования Producer-Consumer, вы можете создать повторно используемый объект NSBlockOperation, отделяя каждый вызов для доступа к словарю в их собственном блоке выполнения:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Doing something...");
}];
//you can add more blocks
[operation addExecutionBlock:^{
NSLog(@"Another block");
}];
[operation setCompletionBlock:^{
NSLog(@"Doing something once the operation has finished...");
}];
[queue addOperation:operation];
Очередь операций предоставляет собственные потоки для выполнения своих операций, поэтому нет необходимости создавать свои собственные. Поскольку в очередях операций используется GCD, операции всегда выполняются в отдельном потоке, независимо от того, имеют ли они соответствующие обозначения как асинхронные и синхронные.
Это должно упростить ваш код, особенно за счет исключения кода, связанного с очередью отправки. Какой беспорядок!
Наконец, создайте метод глобального метода доступа, добавив словарь в AppDelegate, который:
Внедряет синглтон
Выполняет инициализацию только после того, как метод или класс впервые ссылаются на словарь
- Работает только с изменяемой копией, создавая новый изменяемый словарь для замены предыдущего
Вот еще один вариант, который Apple предлагает в своей документации для разработчиков (я скопировал это непосредственно из Руководство по программированию параллелизма ):
Использование диспетчерских семафоров для регулирования использования ограниченных ресурсов, если
задачи, которые вы отправляете в очереди отправки, имеют некоторый конечный доступ
ресурс, вы можете использовать диспетчерский семафор для регулирования
количество задач, одновременно получающих доступ к этому ресурсу. Отправка
Семафор работает как обычный семафор с одним исключением. когда
ресурсы доступны, получение посылки занимает меньше времени
семафор, чем для приобретения традиционного системного семафора. это
потому что Grand Central Dispatch не вызывает в ядро
для этого конкретного случая. Единственный раз, когда он вызывает в ядре
когда ресурс недоступен и система должна парковать
нить, пока семафор не будет сигнализировать. Семантика для использования
Семафор рассылки выглядит следующим образом:
1. Когда вы создаете семафор (используя функцию dispatch_semaphore_create), вы можете указать положительное целое число, указывающее число
доступные ресурсы.
2. В каждой задаче вызовите dispatch_semaphore_wait, чтобы дождаться семафора.
3. Когда вызов ожидания вернется, приобретите ресурс и сделайте свою работу.
4. По завершении работы с ресурсом отпустите его и отправьте сигнал семафору, вызвав функцию dispatch_semaphore_signal. Для
Пример того, как работают эти шаги, рассмотрим использование файловых дескрипторов
в системе. Каждой заявке дается ограниченное количество файлов
дескрипторы для использования. Если у вас есть задача, которая обрабатывает большое количество
файлы, вы не хотите открывать так много файлов одновременно, что вы запускаете
вне файловых дескрипторов. Вместо этого вы можете использовать семафор, чтобы ограничить
количество файловых дескрипторов, используемых одновременно
код обработки файла. Основные части кода, которые вы бы включили
в ваших задачах выглядит следующим образом: // Создать семафор, указав
начальный размер пула dispatch_semaphore_t fd_sema =
dispatch_semaphore_create (getdtablesize () / 2); // Ждем свободного
дескриптор файла dispatch_semaphore_wait (fd_sema,
DISPATCH_TIME_FOREVER); fd = open ("/ etc / services", O_RDONLY); //
Отпустите дескриптор файла, когда закончите close (fd);
dispatch_semaphore_signal (fd_sema); Когда вы создаете семафор, вы
укажите количество доступных ресурсов. Это значение становится
переменная начального числа для семафора. Каждый раз, когда вы ждете на
семафор, функция dispatch_semaphore_wait уменьшает значение
переменная на 1. Если полученное значение отрицательно, функция сообщаетядро, чтобы заблокировать ваш поток.С другой стороны, dispatch_semaphore_signalfunction увеличивает переменную count на 1, чтобы указать, что ресурс был освобожден.Если есть задачи, заблокированные и ожидающие ресурса, одна из них впоследствии разблокируется и может выполнять свою работу.