Я использую следующий метод, чтобы попытаться синхронно получить токен доступа OAuth в течение 10 секунд, иначе верните нуль. Он отлично работает, однако в качестве упражнения я хотел бы преобразовать свой код для использования семафора.Использовать наблюдателя для семафора сигнала?
Runloop версия
- (NSString*)oAuthAccessToken
{
@synchronized (self)
{
NSString* token = nil;
_authenticationError = nil;
if (_authentication.accessToken)
{
token = [NSString stringWithFormat:@"Bearer %@", _authentication.accessToken];
}
else
{
[GTMOAuth2ViewControllerTouch authorizeFromKeychainForName:_keychainName authentication:_authentication];
[_authentication authorizeRequest:nil delegate:self didFinishSelector:@selector(authentication:request:finishedWithError:)];
for (int i = 0; i < 5; i++)
{
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
if (_authentication.accessToken)
{
token = [NSString stringWithFormat:@"Bearer %@", _authentication.accessToken];
break;
}
else if (_authenticationError)
{
break;
}
}
}
// LogDebug(@"Returning token: %@", token);
return token;
}
}
Семафор Версия
семафора версия кода идет немного что-то вроде этого:
- (NSString*)oAuthAccessToken
{
@synchronized (self)
{
NSString* token = nil;
_authenticationError = nil;
if (_authentication.accessToken)
{
token = [NSString stringWithFormat:@"Bearer %@", _authentication.accessToken];
}
else
{
_authorizationSemaphore = dispatch_semaphore_create(0);
dispatch_async(_authorizationRequestQueue, ^(void)
{
[GTMOAuth2ViewControllerTouch authorizeFromKeychainForName:_keychainName authentication:_authentication];
[_authentication authorizeRequest:nil delegate:self didFinishSelector:@selector(authentication:request:finishedWithError:)];
});
dispatch_semaphore_wait(_authorizationSemaphore, DISPATCH_TIME_FOREVER);
if (_authentication.accessToken)
{
token = [NSString stringWithFormat:@"Bearer %@", _authentication.accessToken];
}
}
return token;
}
}
Попался !!! GTMOAuth2 иногда возвращается немедленно
- Когда GTMOAuth2 нужно попасть в сеть, она вызывает обратно через метод делегата. В этом методе я передаю свой семафор.
- Иногда GTMOAuth2 может немедленно вернуться. Проблема заключается в том, что метод возвращает void.
Как я могу сигнализировать о моем семафоре в последнем случае? Если я добавлю наблюдателя в authentication.assessToken, он будет запущен?
Используйте ReactiveCocoa! Это потрясающая библиотека для KVO и многое другое. Сигналы - ваш друг в таких случаях. – allprog
Спасибо, я попробую! , , Кстати, получается, что да, наблюдатель работает отлично. –