Я застрял!
Я пытаюсь создать пользовательский модальный диалог. Я хотел бы, чтобы он работал аналогично NSSavePanel, используя блок в качестве обработчика завершения.
Я скопировал только те важные фрагменты, которые, по моему мнению, необходимы.
@implementation ModalWindowController
- (void)makeKeyAndOrderFront:(id)sender
modalToWindow:(NSWindow*)window
sourceRect:(NSRect)rect
completionHandler:(void (^)(NSInteger result))handler {
_handler = [handler retain];
session = [NSApp beginModalSessionForWindow:[self window]];
[[NSApplication sharedApplication] runModalSession:session];
[[self window] makeKeyAndOrderFrontCentered:self expandingFromFrame:rect];
}
- (IBAction)okButtonPressed:(id)sender {
[[self window] orderOut:self];
_handler(NSOKButton);
[NSApp endModalSession:session];
}
@end
Теперь я могу назвать это, используя код:
[self.modalWindowController makeKeyAndOrderFront:self
modalToWindow:[[self view] window]
sourceRect:sr
completionHandler:^(NSInteger result) {
NSLog(@"Inside Block");
if ( result == NSOKButton ) {
// do something interesting here
}
}];
NSLog(@"Errg");
Все идет хорошо, однако, после того, как метод makeKeyAndOrderFront: modalToWindow: sourceRect: завершениюHandler: завершил, он не блокирует поток, поэтому «Errg» будет напечатан, даже если пользователь не выбрал «ok» или «отменить». В этом месте отображается модальное окно, где пользователь нажимает кнопку ОК, и затем выполняется блок _handler. Однако, если я пытаюсь получить доступ к локальным переменным в блоке, и приложение вылетает, поскольку все уже очищено.
Каков наилучший подход к блокировке основного потока из метода makeKeyAndOrderFront: ...? Это правильный подход к реализации обработчика завершения с использованием блоков?