У меня есть модельный объект и оконный контроллер.Я хотел бы, чтобы они могли общаться через уведомления.Я создаю оба во время метода App Delegate -applicationDidFinishLaunching:
.Я добавляю наблюдателей после загрузки окна контроллера окна, например так:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
WordSetWindowController* windowController = [[WordSetWindowController alloc] initWithWindowNibName:@"WordSetWindowController"];
model = [[WordSetModel alloc] init];
NSWindow* window = windowController.window;
[[NSNotificationCenter defaultCenter] addObserver:windowController
selector:@selector(handleNotification:)
name:kNotification_GeneratingPairs
object:model];
[[NSNotificationCenter defaultCenter] addObserver:windowController
selector:@selector(handleNotification:)
name:kNotification_ProcessingPairs
object:model];
[[NSNotificationCenter defaultCenter] addObserver:windowController
selector:@selector(handleNotification:)
name:kNotification_UpdatePairs
object:model];
[[NSNotificationCenter defaultCenter] addObserver:windowController
selector:@selector(handleNotification:)
name:kNotification_Complete
object:model];
[model initiateSearch];
}
Метод -iniateSearch
запускает некоторые потоки для выполнения некоторых ресурсоемких вычислений в фоновом режиме.Я хотел бы, чтобы эти потоки отправляли уведомления, чтобы я мог обновлять интерфейс во время обработки.Это выглядит так:
- (void)initiateSearch;
{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotification_GeneratingPairs
object:self];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// ... do the first part of the calculations ...
// Notify the UI to update
self->state = SearchState_ProcessingPairs;
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotification_ProcessingPairs
object:self];
});
// ... Do some more calculations ...
// Notify the UI that we're done
self->state = SearchState_Idle;
dispatch_sync(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotification_Complete
object:self];
});
});
}
Первое уведомление работает правильно, но ни одно из уведомлений, которые происходят в вызове dispatch_async()
, никогда не вызывает вызов обработчика уведомлений.Я попытался вызвать -postNotificationName::
как в фоновом потоке, так и в потоке пользовательского интерфейса (как с помощью dispatch_async(dispatch_get_main_queue(),...)
, так и путем вызова -performSelectorOnMainThread:::
), но ни один из них не дал никакого эффекта.
Любопытно, я добавил вызов черезNSTimer
, который ждет 5 секунд после большого вызова dispatch_async()
в конце -initiateSearch:
и обнаружил, что, хотя все это происходит в основном потоке пользовательского интерфейса, он также не запускает обработчик уведомлений.Если я просто позвоню postNotification:::
сразу после возврата вызова dispatch_async()
, он будет работать правильно, хотя.
Из этого я заключаю, что наблюдатели каким-то образом удаляются из центра уведомлений, несмотря на то, чточто мой код никогда не вызывает -removeObserver :.Почему это происходит, и как я могу или не допустить этого, или куда я могу переместить мои звонки на -addObserver
, чтобы на них это не влияло?