Im пытается понять обработчики завершения & блоков. Я считаю, что вы можете использовать блоки для многих глубоких программных вещей без обработчиков завершения, но я думаю, что понимаю, что обработчики завершения основаны на блоках. (Так что в основном обработчики завершения требуют блоки, но не наоборот).Как обработчик завершения работает на iOS?
Так что я увидел этот код в интернете о старых рамках твиттере:
[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, очевидно, гомолог выполнения RequestWithHandler
- , к сожалению, это немного сложнее, потому что есть вызов GCD на пути ...
Но, в основном, запрос выполнен и с ошибкой обрабатывается, данные обрабатываются, а затем проверяется обработчик. Мой вопрос: как эта часть обработчика работает? Я понимаю, что если он существует, он отправит обратно в основную очередь и вернет userArray. Но как он знает, ждать, пока userArray будет заполнен? Я предполагаю, что меня смущает тот факт, что метод: блок в этом случае имеет другой блок внутри него, вызов dispatch_async. Я предполагаю, что Im ищет логику, которая на самом деле делает вещи и знает, КОГДА возвращать responseData и urlResponse. Я знаю, что это не то же приложение, но я не вижу кода для выполненияRequestWithHandler.
2 вопроса: (1) почему вы говорите в шаге 3 «время проходит, пока у фоновой очереди нет свободных ресурсов». Почему у него НЕ есть свободные ресурсы? на этапах 7/8 с основной очередью. Почему у него НЕ есть свободные ресурсы и, следовательно, придется ждать? И самое главное, как обработчик «обрабатывает» userArray для его отправки? Какая часть кода сообщает обработчику отправить данные обратно тому, кто его вызвал? – marciokoko
См. Мой отредактированный ответ. – deekay
Что необходимо для преобразования 'NSData' в' NSString', а затем обратно в 'NSData'? – Rishab