Я просил и пытался понять, как работают обработчики завершения. Я использовал немало, и я читал много учебников. я опубликую тот, который я использую здесь, но я хочу, чтобы иметь возможность создавать свои собственные, не используя чужой код в качестве ссылки.Что делает обработчик завершения выполнять блок, когда ваша задача интересна?
Я понимаю, этот обработчик завершения, когда этот метод вызывающий:
-(void)viewDidLoad{
[newSimpleCounter countToTenThousandAndReturnCompletionBLock:^(BOOL completed){
if(completed){
NSLog(@"Ten Thousands Counts Finished");
}
}];
}
, а затем в вызываемом методе:
-(void)countToTenThousandAndReturnCompletionBLock:(void (^)(BOOL))completed{
int x = 1;
while (x < 10001) {
NSLog(@"%i", x);
x++;
}
completed(YES);
}
Тогда я Сорта придумал с этим на основе многих SO сообщений:
- (void)viewDidLoad{
[self.spinner startAnimating];
[SantiappsHelper fetchUsersWithCompletionHandler:^(NSArray *users) {
self.usersArray = users;
[self.tableView reloadData];
}];
}
, который перезагрузит табличное представление получателями данных после вызова это метод:
typedef void (^Handler)(NSArray *users);
+(void)fetchUsersWithCompletionHandler:(Handler)handler {
NSURL *url = [NSURL URLWithString:@"http://www.somewebservice.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
[request setHTTPMethod: @"GET"];
**// We dispatch a queue to the background to execute the synchronous NSURLRequest**
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Perform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) { **// If an error returns, log it, otherwise log the response**
// Deal with your error
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSLog(@"HTTP Error: %d %@", httpResponse.statusCode, error);
return;
}
NSLog(@"Error %@", error);
return;
}
**// So this line won't get processed until the response from the server is returned?**
NSString *responseString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
NSArray *usersArray = [[NSArray alloc] init];
usersArray = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSASCIIStringEncoding] options:0 error:nil];
// Finally when a response is received and this line is reached, handler refers to the block passed into this called method...so it dispatches back to the main queue and returns the usersArray
if (handler){
dispatch_sync(dispatch_get_main_queue(), ^{
handler(usersArray);
});
}
});
}
можно увидеть в примере счетчика, что вызываемый метод (с пройденным блоком) никогда не выйти из цикла до тех пор, пока не будет сделан. Таким образом, часть «завершения» на самом деле зависит от кода внутри вызываемого метода, а не от блока, переданного в него?
В этом случае часть «завершения» зависит от того, является ли вызов NSURLRequest синхронным. Что, если это было асинхронно? Как я смогу удержаться от вызова блока до тех пор, пока мои данные не будут заполнены NSURLResponse?
Спасибо @RobNapier, это именно тот ответ, который я искал. Я пытаюсь начать создавать свои собственные обработчики завершения. Я пытался исследовать встроенные в UIKit, такие как анимации UIView, но, конечно, они частные :). Последнее, когда вы говорите: «Если это было асинхронно, вам нужно сохранить блок в переменной экземпляра и вызвать это, когда асинхронная операция завершилась «как я узнаю, когда асинхронный оператор будет завершен, если эта операция не имеет обработчика завершения? Как обработка изображений? – marciokoko
Большинство асинхронных интерфейсов либо имеют блок завершения, либо метод делегата, чтобы указать, когда они будут завершены. Если он не предоставляет способ сообщить вам, что это сделано, это не очень хорошо разработанный асинхронный интерфейс. –
Итак, возможно, я подумал о том, как вы на самом деле разрабатываете метод, который должен постоянно проверять результаты, чтобы предоставить обработчик завершения или обратный вызов пользователю этого API. И я думаю, ответ заключается в том, что это зависит от того, что ждет этот метод, и мне нужно будет создать соответствующий код, чтобы убедиться, что что-то было возвращено, чтобы обеспечить обработчик завершения, да?Например, я мог бы использовать NSTimer, который каждые 5 секунд проверяет, был ли возвращен NSURLResponse, а затем предоставлен обработчик завершения? Как пример цикла! – marciokoko