2012-04-19 2 views
1

Я использую клиентский объект AFNetworking, который делает асинхронный запрос для XML-документа и анализирует его.NSNotificationCenter - способ ждать уведомления для публикации без блокировки основной темы?

Также с использованием NSNotificationCenter для отправки уведомления, когда документ завершил разбор.

Есть ли способ для ждать для уведомления, которое будет опубликовано без блокировки основной темы?

код например:

-(void)saveConfiguration:(id)sender { 

    TLHTTPClient *RESTClient = [TLHTTPClient sharedClient]; 

    // Performs the asynchronous fetching....this works. 
    [RESTClient fetchActiveUser:[usernameTextField stringValue] withPassword:[passwordTextField stringValue]]; 

    /* 
    * What do I need here ? while (xxx) ? 
    */ 

    NSLog(@"Fetch Complete."); 

} 

В принципе мне интересно, какой код мне нужно в указанной выше области, чтобы гарантировать, что функция не ждет, пока выборки была завершена?

Как сейчас, я увижу «Fetch Complete». в консоли отладки до того, как выборка завершена.

Я попытался добавить флаг BOOL к классу TLHTTPClient:

BOOL fetchingFlag; 

, а затем пытается:

while([RESTClient fetchingFlag]) { NSLog(@"fetching...); } 

Когда этот класс получает уведомление он устанавливает RESTClient.fetchingFlag = FALSE; который должен технически убить цикл while? За исключением цикла while while выполняется бесконечно?!

+0

Вы могли подождать в другой ветке? – MechEthan

+0

Вы можете разобрать раздельную партию в отдельной теме – Kamal

+7

Если вы зарегистрируетесь для получения уведомления, вы уже ждёте, не блокируя основной поток, не так ли? –

ответ

2

В принципе, мне интересно, какой код мне нужен в указанной выше области, чтобы гарантировать, что функция ждет, пока выборка не будет завершена?

Необходимо no code. Не ставьте ничего в метод после запуска извлечения, и ничего не произойдет. Ваша программа будет «ждать» (она будет обрабатывать другой вход) до тех пор, пока уведомление не будет получено.

В методе обработчика уведомлений поместите все, что вам нужно сделать, когда выборка завершена. Это (одна) точка (ы) уведомлений и другие схемы обратного вызова - ваш объект не будет делать ничего дальше, пока не получит уведомление о том, что пришло время действовать.

Есть ли способ подождать, когда уведомление будет опубликовано без блокировки основного потока?

Вот как это работает.

+0

После того, что вы сказали, а затем переосмыслив то, что я пытаюсь выполнить и пересматриваю свой код, вы действительно были правы! благодаря! –

+0

Рад, что я мог помочь. –

0

Если вам не нужно сообщать о нескольких объектах после завершения задачи, вы можете добавить обработчик завершения (блок objc) в метод -fetchActiveUser:withPassword: (так что это станет чем-то вроде -fetchActiveUser:withPassword:completionHandler: и добавит код, который будет выполнен в . обработчик завершения

пример, позволяет сказать, что ваш метод -fetchActiveUser:withPassword:completionHandler: выглядит следующим образом:

- (void)fetchActiveUser:(NSString *)user 
      withPassword:(NSString *)pass 
     completionHandler:(void (^)(TLUser *user, NSError *error))handler 
{ 
    NSURL *URL     = [NSURL URLWithString:@"http://www.website.com/page.html"]; 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];  
    NSOperationQueue *queue  = [NSOperationQueue currentQueue]; 
    [NSURLConnection sendAsynchronousRequest:request 
             queue:queue 
          completionHandler:^ (NSURLResponse *response, NSData *data, NSError *error) 
    { 
     if (!handler) 
     { 
      return 
     }; 

     if (data) 
     { 
      TLUser *user = [TLUser userWithData:data]; 

      if (user) 
      { 
       handler(user, nil); 
      } 
      else 
      { 
       NSError *error = // 'failed to create user' error ... 
       handler(nil, error); 
      } 
     } 
     else 
     { 
      handler(nil, error); 
     } 
    }]; 
} 

обработчик завершения будет вызываться всякий раз, когда задача закончена Это будет либо возвращать объект TLUser или ошибку. если что-то пошло не так (плохая связь, d ata изменился во время разбора и т. д.).

Вы сможете вызвать метод как это:

- (void)saveConfiguration:(id)sender 
{ 
    TLHTTPClient *RESTClient = [TLHTTPClient sharedClient]; 


    // Performs the asynchronous fetching 

    [RESTClient fetchActiveUser:[usernameTextField stringValue] 
        withPassword:[passwordTextField stringValue] 
       completionHandler:^ (TLUser *user, NSError *error) 
    { 
     if (user) 
     { 
      NSLog(@"%@", user); 
     } 
     else 
     { 
      NSLog(@"%@", error);  
     } 
    }]; 
} 

Конечно, в этом примере я использовал сборку в асинхронных методах NSURLConnection в смене AFNetworking, но вы должны быть в состоянии чтобы получить общую идею.