2015-05-15 2 views
1

У меня возникли проблемы с получением NSNotification. Я могу сказать, что мой сетевой вызов эффективен на стороне сервера и что ответ сервера получен на сетевом уровне в моем приложении, но когда мой класс сетевого уровня делает последний шаг отправки NSNotification в UIViewController, это уведомление никогда не получал. В результате мое приложение зависает, хотя все остальное работает по назначению.Не принимается NSNotification

Вот UIViewController, который инициирует все:

- (void) updateAffiliations 
{ 
    [self.activityIndicator startAnimating]; 
    self.activityIndicator.hidden = NO; 

    Updater *updater = [[Updater alloc] init]; 
    NSDictionary *clearTextParams = [updater makeDictionary]; 
    NSString *phpPath = @"updateRecord.php"; 
    NSDictionary *parameters = [[SharedCipher sharedCipher] encryptParameters:clearTextParams]; 

    _preferenceUpdateResponse = @"preferencesResponse"; 

    [[NSNotificationCenter defaultCenter] addObserver : self 
              selector : @selector(preferenceUpdateResult:) 
               name : _preferenceUpdateResponse 
               object : nil]; 

    [[SharedNetworkObject sharedNetworkObject] sendHttpPost : phpPath 
               parameters : parameters 
              notificationName : _preferenceUpdateResponse]; 
    NSLog(@"sent"); 
} 

- (void) preferenceUpdateResult: (NSNotification *) notification 
{ 
    NSLog(@"response received from network layer"); 
    NSDictionary *dict = [notification userInfo]; 

    [self.activityIndicator stopAnimating]; 
    self.activityIndicator.hidden = YES; 

    //... 
} 

Сетевой уровень, что я имею в виду одноэлементно класс называется SharedNetworkObject. Я использовал этот класс несколько раз, и это единственный случай, когда эта проблема происходит:

- (void) sendHttpPost : (NSString *) phpPath 
      parameters : (NSDictionary *) parameters 
    notificationName : (NSString *) notificationName 
{ 
    NSLog(@"sending http post to : %@", phpPath); 
    NSLog(@"params: %@", parameters); 

    [self POST : phpPath 
    parameters : parameters 
     success : ^(NSURLSessionDataTask *task, id responseObject) 
      { 
       NSLog(@"response object: %@", responseObject); 
       NSLog(@"broadcasting notification to : %@", notificationName); 
       [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:nil userInfo:responseObject]; 
      } 

     failure : ^(NSURLSessionDataTask *task, NSError *error) 
      { 
       NSLog(@"Shared Network Object error: %@", error); 
       NSDictionary * userInfo = @{ @"result" : @"failure", @"error" : error }; 
       [[NSNotificationCenter defaultCenter] postNotificationName : notificationName object:nil userInfo:userInfo]; 
      }]; 
} 

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

отправки HTTP POST для: updateRecord.php
Params: {
шифротекста = "игнорировать это, много зашифрованного jibberish";
"device_iv" = "0Q7yxsTpzQEaDGPpJ96JrA ==";
paddLength = 11;
"session_id" = 845903271;
}
отправлено
объект ответа: {
message = "успешно обновленная запись";
результат = успех;
} уведомление
вещания на: preferencesResponse

Этот вывод выглядит отлично, за исключением того, что она является неполной. Там должна быть одна последняя строка, которая говорит

ответ, полученный от сетевого уровня

Но это никогда не выводит, потому что уведомление никогда не получено. Я проверил все обычные причины, которые приводят к тому, что уведомления никогда не возвращаются, и я думаю, что это правильно. Фактически, я использую эту точную картину три раза в других местах, и все они работают отлично.

Кто-нибудь видит, что я делаю неправильно здесь? Возможно, это проблема с потоками?

Большое спасибо!

ответ

0

я, наконец, понял это. У меня был предыдущий наблюдатель, который не был удален, когда это уведомление было отправлено.Я удивлен, что это создало проблему, поскольку другое имя уведомления было совершенно иным, чем это, но как только я переупорядочил код, чтобы удалить этого другого наблюдателя, прежде чем я зарегистрировал новый, проблема будет отсутствовать. Живи и учись, я думаю ...

Спасибо за помощь, @cbiggin!

3

Почти наверняка проблема с потоками, так как сетевой код выполняется в фоновом потоке, но вы хотите, чтобы ваше уведомление принималось в основном потоке (для обновления ваших индикаторов активности и активности).

К счастью, простое решение ... завернуть их в dispatch_async звонки:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:nil userInfo:responseObject]; 
}); 
+4

NSNotificationCenter будет поставлять на любой поток, который NSNotification отправляется, поэтому, в то время как OP не сможет обновить пользовательский интерфейс, все равно должна быть строка, написанная на консоли через NSLog – chedabob

+0

Спасибо. Не работает, к сожалению. – Alex

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