2

Я использую следующий метод, чтобы попытаться синхронно получить токен доступа 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, он будет запущен?

+1

Используйте ReactiveCocoa! Это потрясающая библиотека для KVO и многое другое. Сигналы - ваш друг в таких случаях. – allprog

+0

Спасибо, я попробую! , , Кстати, получается, что да, наблюдатель работает отлично. –

ответ

3

Я не знаком с библиотекой GTMOAuth2, но authentication.accessToken - это свойство, поэтому, похоже, что-то не мешает ему быть совместимым с KVO. Добавление наблюдателя должно работать для вас во всех случаях, как для асинхронизации, так и для синхронизации. Поэтому я бы рассмотрел только асинхронный случай.

Если вы хотите сделать свое решение еще более чистым, то вам обязательно нужно попробовать Reactive Cocoa.

+1

Да, оказывается, все работает отлично. Я думаю, что к тому моменту, когда я опубликовал, я был наиболее способ решить мою проблему, но эта информация может быть полезной для других, поэтому оставим все здесь. , Я сам изучил две вещи: a) Наблюдатель должен работать как для синхронизации, так и для асинхронной работы. B) Проверьте Reactive Cocoa –

+1

@ JasperBlues Мне обязательно нужно попробовать тайфун. Я смотрел на него некоторое время назад, но теперь, когда он уже готов к развертыванию, я полностью готов попробовать его. – allprog

+0

Ваша обратная связь будет очень полезной для нас :) –

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