можно ли использовать уведомление для обратной связи с основным потоком приложения IOS? (cf performSelectorOnMainThread)


Можно ли использовать уведомление для обратной связи с основным потоком приложения IOS? (ср. performSelectorOnMainThread). То есть, есть ли какие-нибудь готчи для этой цели?

Фон

  • хотите вызвать основной поток пользовательского интерфейса из фонового потока (например, performSelectorInBackground)
  • может использовать performSelectorOnMainThread для обратной связи, но интересно, можно ли использовать уведомление?

Например

 [[NSNotificationCenter defaultCenter] postNotificationName:@"ModelChanged" object:self];
2 13

2 ответа:

На самом деле есть готча; вы врежетесь случайно! Это был мой личный опыт. Это связано с тем, что объект, получающий уведомление, делает это в том же потоке, что и отправитель уведомления.

Из документации Apple iOS по центрам уведомлений :

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

Это неизбежно вызовет у вас головную боль.

Если уведомление получает что-то в основном потоке, я обнаружил, что попадание в основной поток из фонового потока для выдачи уведомления-самый безопасный способ сделать это. Это довольно просто сделать:

//Call this to post a notification and are on a background thread      
- (void) postmyNotification{
  [self performSelectorOnMainThread:@selector(helperMethod:) withObject:Nil waitUntilDone:NO];
}

//Do not call this directly if you are running on a background thread.
- (void) helperMethod{
  [[NSNotificationCenter defaultCenter] postNotificationName:@"SOMENAME" object:self];
}

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

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

Надеюсь, что была полезна.

Да, уведомления могут быть использованы для этой цели. вы можете использовать любой метод, который вам нравится (протоколы, уведомления, прямые сообщения) для связи между объектами в потоках. Какой из них вы выберете, зависит от того, что вы считаете наиболее подходящим. Уведомления хороши, когда объект, отправляющий уведомление, ничего не знает об объектах, наблюдающих за уведомлением. Если вы отправляете сообщение (например, performSelectorOnMainThread), то объект, отправляющий сообщение, должен знать об объекте, которым оно является отправка сообщения (обычно через протокол).