Как работает обработчик завершения на iOS?

Я пытаюсь понять обработчики завершения & блоки. Я полагаю, что вы можете использовать блоки для многих вещей глубокого программирования без обработчиков завершения, но я думаю, что я понимаю, что обработчики завершения основаны на блоках. (Так что в основном обработчикам завершения нужны блоки, а не наоборот).

Итак, я увидел этот код в Интернете о старой платформе Twitter:

[twitterFeed performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
        if (!error) {
            self.successLabel.text = @"Tweeted Successfully";
            [self playTweetSound];
        } else {
            // Show alert
        }
        // Stop indicator 
        sharedApplication.networkActivityIndicatorVisible = NO;
    }];

Здесь мы вызываем метод, который выполняет вещи (выполняет TWRequest) и возвращает, когда закончите с responseData & urlResponse & ошибка. Только когда он возвращается, он выполняет блок, который проверяет предоставленный и останавливает индикатор активности. ИДЕАЛЬНО!

Теперь у меня есть настройка для другого приложения, которое работает, но яЯ пытаюсь собрать кусочки вместе:

@interface
Define an ivar
typedef void (^Handler)(NSArray *users);
Declare the method
+(void)fetchUsersWithCompletionHandler:(Handler)handler;

@implementation
+(void)fetchUsersWithCompletionHandler:(Handler)handler {
    //...Code to create NSURLRequest omitted...
    __block NSArray *usersArray = [[NSArray alloc] init];

    //A. Executes the request 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

        // Peform the request
        NSURLResponse *response;
        NSError *error = nil;
        NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
                                                     returningResponse:&response
                                                                 error:&error];
        // Deal with your error
        if (error) {
            }
            NSLog(@"Error %@", error);
            return;
        }
        // Else deal with data
        NSString *responseString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
        usersArray = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSASCIIStringEncoding] options:0 error:nil];

        // Checks for handler & returns usersArray to main thread - but where does handler come from & how does it know to wait tip usersArray is populated?
        if (handler){
            dispatch_sync(dispatch_get_main_queue(), ^{
            handler(usersArray);
            });
        }
    });
}

Вот мое понимание:

fetchUsersWithCompletionHandler, очевидно, является гомологом executeRequestWithHandlerк сожалению, это немного сложнее, потому что есть GCD-вызов ...

Но в основном запрос выполняется, и ошибка обрабатывается, данные обрабатываются, а затем проверяется обработчик. Мой вопрос: как работает эта часть обработчика? Я понимаю, что если он существует, он отправит обратно в основную очередь и вернет массив Users. Но как он узнает, пока не будет заполнен usersArray? Я думаю, что меня смущает тот факт, что метод: block в этом случае имеет внутри другой блок, вызов dispatch_async. Я думаю, что я ищу, это логика, которая на самом деле делает вещи и знает, когда вернуть responseData и urlResponse. Я знаю, что это не то же самое приложение, но я не вижу код для executeRequestWithHandler.

Ответы на вопрос(1)

Ваш ответ на вопрос