私は立ち往生しています!
カスタム モーダル ダイアログを作成しようとしています。ブロックを完了ハンドラーとして使用して、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:completionHandler: が完了した後、スレッドはブロックされないため、ユーザーが「OK」または「キャンセル」を選択していなくても「Errg」が出力されます。この時点でモーダル ウィンドウが表示され、ユーザーが [OK] をクリックすると、_handler ブロックが実行されます。ただし、ブロック内のローカル変数にアクセスしようとすると、すべてが既にクリーンアップされているため、アプリがクラッシュします。
makeKeyAndOrderFront:... メソッドからメインスレッドをブロックする最良の方法は何ですか? これは、ブロックを使用して完了ハンドラーを実装するための正しいアプローチですか?