Сначала рассмотрим пример работ с функцией dispatch_after:
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
double delayInSeconds = 2.0;
dispatch_time_t delayInNanoSeconds =
dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_queue_t concurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after(delayInNanoSeconds, concurrentQueue, ^(void){
/* Здесь выполняются требуемые операции. */
});
// Точка переопределения для настройки после запуска приложения
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Как видите, параметр задержки в наносекундах для функций dispatch_after и dispatch_after_f должен относиться к типу dispatch_time_t, который является абстрактным представлением абсолютного времени. Чтобы получить значение этого параметра, можно пользоваться функцией dispatch_time так, как показано в данном образце кода. Вот параметры, которые можно сообщать функции dispatch_time.
• Исходное время — если обозначить этот параметр через B, а приращение времени (Delta Parameter) — через D, то результирующее время от этой функции будет равно B+D. Для этого параметра можно задать значение DISPATCH_TIME_NOW, определив таким образом в качестве базового времени настоящий момент , а потом указать приращение, добавляемое к этому времени, используя дельта-параметр.
Приращение, добавляемое к базовому времени, — этот параметр дает количество наносекунд, добавляемых к параметру исходного времени для получения результата данной функции.
Например, чтобы задать временной промежуток 3 с начиная от настоящего момента, можно написать следующий код:
dispatch_time_t delay =
dispatch_time(DISPATCH_TIME_NOW, 3.0f * NSEC_PER_SEC);
А вот так задается период 0,5 с от настоящего момента:
dispatch_time_t delay =
dispatch_time(DISPATCH_TIME_NOW, (1.0 / 2.0f) * NSEC_PER_SEC);
Теперь рассмотрим, как можно использовать функцию dispatch_after_f:
void processSomething(void *paramContext){
/* Здесь происходит обработка. */
NSLog(@"Processing…");
}
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
double delayInSeconds = 2.0;
dispatch_time_t delayInNanoSeconds =
dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_queue_t concurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after_f(delayInNanoSeconds,
concurrentQueue,
NULL,
processSomething);
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
// Точка переопределения для настройки после запуска приложения
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Разделы 7.1 и 7.4.
7.8. Однократное выполнение задач с помощью GCD
Необходимо убедиться в том, что определенный фрагмент кода выполняется один раз за весь жизненный цикл приложения, даже если он вызывается неоднократно из разных точек программы (в качестве примера можно привести инициализацию синглтона).
Воспользуйтесь функцией dispatch_once.
Выделение и инициализация синглтона — одна из таких задач, которые должны происходить один, и только один раз за весь жизненный цикл приложения. Уверен, что вы можете вспомнить и другие аналогичные сценарии.
GCD позволяет указывать идентификатор для фрагмента кода при попытке выполнить этот код. Если GCD обнаруживает, что данный идентификатор уже передавался фреймворку ранее, то система не будет вновь выполнять этот блок кода. Функция, которая обеспечивает выполнение подобных задач, называется dispatch_once. Она может принимать два параметра.
• Маркер — маркер типа dispatch_once_t, содержащий сгенерированную GCD метку при первом выполнении блока кода. Если вы хотите, чтобы блок кода был выполнен лишь один раз, нужно указывать для данного метода один и тот же маркер независимо от того, когда он активизируется в приложении. Такой пример мы вскоре рассмотрим.
Блоковый объект — блоковый объект, выполняемый не более одного раза. Блоковый объект не возвращает никаких значений и не принимает никаких параметров.
dispatch_once всегда выполняет свою задачу в актуальной очереди, используемой кодом, который делает вызов. Это может быть как последовательная, так и параллельная или главная очереди.
Например:
static dispatch_once_t onceToken;
void (^executedOnlyOnce)(void) = ^{
static NSUInteger numberOfEntries = 0;
numberOfEntries++;
Читать дальше
Конец ознакомительного отрывка
Купить книгу