2013-10-11 2 views
1

Я новичок в асинхронных обратных вызовах и получил разные советы. Мне нужно выполнить асинхронные обратные вызовы, и после многих часов исследований я до сих пор не знаю, следует ли использовать блоки или GCD и очереди. Любые указатели приветствуются.Обратные вызовы синхронизации - блок против очереди GCD

OK. Так что я действительно спрашивал:

«для того, чтобы использовать« асинхронные »обратные вызовы, нужно ли использовать GCD и очереди?»

Что я собираю из ответов, так это то, что ответ ДА. Определенно GCD и очереди внутри блоки.

Моя путаница вытекает из того факта, что мне дали направление, что все, что мне было нужно, это блок, как код ниже:

[UIView animateWithDuration:.4f 
       animations:^{ 
        flashView.alpha = 0.f; 
       } 
       completion:^(BOOL finished){ 
        [flashView removeFromSuperview]; 
       } 
]; 

Но что я вижу в ответах здесь является то, что выше блок недостаточно для создания «асинхронных» обратных вызовов. Вместо этого я DO в-самом деле нужно использовать НОД и очереди внутри блока, как код ниже:

- (void)invokeAsync:(id (^)(void))asyncBlock resultBlock:(void (^)(id))resultBlock errorBlock:(void (^)(id))errorBlock { 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(queue, ^{ 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     id result = nil; 
     id error = nil; 
     @try { 
      result = asyncBlock(); 
     } @catch (NSException *exception) { 
      NSLog(@"caught exception: %@", exception); 
      error = exception; 
     } 
     // tell the main thread 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSAutoreleasePool *secondaryPool = [[NSAutoreleasePool alloc] init]; 
      if (error != nil) { 
       errorBlock(error); 
      } else { 
       resultBlock(result); 
      } 
      [secondaryPool release]; 
     }); 
     [pool release]; 
    }); 
} 
+2

Непонятно, что вы просите. GCD полностью построен вокруг идеи отправки блоков в очереди. Вы не можете отделить GCD от блоков и очередей, они идут вместе. –

+0

@AndrewMadsen Технически вы * можете * использовать GCD с функциями, хотя кто захочет !? –

+0

@ JasperBlues, да, я думал об этом. Я никогда не видел, чтобы кто-либо использовал эти функции отправки на основе функций. Я думаю, они полезны, если вы используете libdispatch в среде без блоков? Во всяком случае, для всех нормальных целей и целей, особенно для новичков, GCD всегда используется с блоками. –

ответ

3

Асинхронный обратный вызов - это тот, где текущий поток продолжает выполнять операторы, и вы отключаете выполнение кода в другом потоке, который будет запущен позже.

Существует несколько технологий для достижения этой цели. В этом примере я вызываю метод cacheImage :, с изображением параметра (только пример) в 4 различных асинхронных способах.

// 1. NSThread 
[NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:self withObject:image]; 

// 2. performSelector... 
[self performSelectorInBackground:@selector(cacheImage:) withObject:image]; 

// 3. NSOperationQueue 
NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cacheImage:) object:image]; 
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; 
[opQueue addOperation:invOperation]; 

// 4. GCD 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [self cacheImage:image]; 
}); 

Гораздо более простой способ заключается в использовании НОДА, потому что у него уже есть готовая нить для вас использовать, вместо того, чтобы создать его самостоятельно с другими вариантами.

Однако, поскольку блоки реализуются как объекты, вы можете действительно использовать блоки без НОД, например:

// block definition 
typedef void (^hello_t)(); 

// method that uses a block as parameter 
-(void) runBlock:(hello_t)hello { 
    hello(); 
} 

// asynchronous execution of a block 
[NSThread detachNewThreadSelector:@selector(runBlock) toTarget:self withObject:^(){ 
    NSLog(@"hi"); 
}]; 

PS: Вам не нужно использовать NSAutoreleasePool вручную, если вы не создадите много много объектов, и вы немедленно освободите память. Кроме того, @try @catch редко используются в Objective-C

+0

Спасибо, Яно. Ваше объяснение очень полно и полезно для меня, когда я понимаю, как использовать «асинхронные» обратные вызовы. – Patricia

2

Не любая точка путаницы здесь. GCD также имеет исполнение блока. GCD API, который поддерживает асинхронное выполнение операций на уровне Unix системы.

Объекты блока - это синтаксическая и временная функция уровня C. Они аналогичны стандартным функциям C, но в дополнение к исполняемому коду они также могут содержать переменные привязки к автоматической (стек) или управляемой (куче) памяти. Поэтому блок может поддерживать набор состояний (данных), которые он может использовать для воздействия на поведение при его выполнении.

Apple разработала блоки с явной целью упростить создание программ для архитектуры потоковой передачи Grand Central Dispatch, хотя она не зависит от этой архитектуры и может использоваться практически так же, как и закрытия на других языках. Apple реализовала блоки как в своей собственной части сборника компиляторов GNU, так и в интерфейсе компилятора Clang LLVM. Языковая поддержка библиотеки времени для блоков также доступна как часть проекта LLVM.

Поэтому вы можете использовать любой из них с одинаковой функциональностью.

+0

Итак, в основном вы говорите мне, что я могу использовать либо для выполнения такого же асинхронного поведения? Thank you, Lucy – Patricia

+1

@Lucy - Если вы используете GCD, вы будете использовать блоки для прохождения в том, что выполняется асинхронно. –

+0

@iAmbitious - я подумал, что ваш комментарий достаточно для того, чтобы сделать асинхронный вызов. Прочтите мое обновленное объяснение. Вы сможете понять мое замешательство в этой теме. Так что вы говорите мне, что мне нужно использовать GCD и очереди с блоками, чтобы сделать «асинхронный» обратный вызов. Я не могу просто использовать блок без GCD и очередей. – Patricia

Смежные вопросы