Можно ли использовать уведомление для связи с основным потоком приложения IOS?(cf executeSelectorOnMainThread) - PullRequest
13 голосов
/ 07 ноября 2011

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

Фон

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

Например

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

Ответы [ 2 ]

20 голосов
/ 07 ноября 2011

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

Из документации 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];
}

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

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

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

8 голосов
/ 07 ноября 2011

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

...