1

Core Data のドキュメント ベースのアプリを作成しようとしていますが、一度に表示できるドキュメントは 1 つだけという制限があります (これはオーディオ アプリであり、多くのドキュメントが一度にノイズを発生させるのは意味がありません)。 .

私の計画は、メニューのアクションにリンクする必要のない方法で NSDocumentController をサブクラス化することでした。これは合理的に進んでいますが、私のアプローチに少し疑問を抱かせる問題に遭遇しました。

以下のコードは、ユーザーが次のことを行う場合を除いて、ほとんどの部分で機能します。 - 既存の「ダーティ」ドキュメントを開いた状態でドキュメントを開こうとする - 保存/保存しない/キャンセル アラートで [キャンセル] をクリックします (これは問題なく動作します) - その後、試行しますドキュメントを再度開くには、何らかの理由で、開くダイアログが表示されても、openDocumentWithContentsOfURL メソッドが再度呼び出されることはありません。

誰でも理由を理解するのを手伝ってもらえますか? または、これを正しく行う方法の例を教えてください。数人によって実装されたに違いないもののように感じますが、10.7+ の例を見つけることができませんでした。

- (BOOL)presentError:(NSError *)error
{
    if([error.domain isEqualToString:DOCS_ERROR_DOMAIN] && error.code == MULTIPLE_DOCS_ERROR_CODE)
        return NO;
    else
        return [super presentError:error];
}

- (id)openUntitledDocumentAndDisplay:(BOOL)displayDocument error:(NSError **)outError
{
    if(self.currentDocument) {
        [self closeAllDocumentsWithDelegate:self
                        didCloseAllSelector:@selector(openUntitledDocumentAndDisplayIfClosedAll: didCloseAll: contextInfo:)
                                contextInfo:nil];

        NSMutableDictionary* details = [NSMutableDictionary dictionary];
        [details setValue:@"Suppressed multiple documents" forKey:NSLocalizedDescriptionKey];
        *outError = [NSError errorWithDomain:DOCS_ERROR_DOMAIN code:MULTIPLE_DOCS_ERROR_CODE userInfo:details];
        return nil;
    }

    return  [super openUntitledDocumentAndDisplay:displayDocument error:outError];
}

- (void)openUntitledDocumentAndDisplayIfClosedAll:(NSDocumentController *)docController
                                      didCloseAll: (BOOL)didCloseAll
                                      contextInfo:(void *)contextInfo
{
    if(self.currentDocument == nil)
        [super openUntitledDocumentAndDisplay:YES error:nil];
}

- (void)openDocumentWithContentsOfURL:(NSURL *)url
                              display:(BOOL)displayDocument
                    completionHandler:(void (^)(NSDocument *document, BOOL documentWasAlreadyOpen, NSError *error))completionHandler NS_AVAILABLE_MAC(10_7)
{
    NSLog(@"%s", __func__);
    if(self.currentDocument) {
        NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[url copy], @"url",
                                                                        [completionHandler copy], @"completionHandler",
                                                                        nil];
        [self closeAllDocumentsWithDelegate:self
                        didCloseAllSelector:@selector(openDocumentWithContentsOfURLIfClosedAll:didCloseAll:contextInfo:)
                                contextInfo:(__bridge_retained void *)(info)];
    } else {
        [super openDocumentWithContentsOfURL:url display:displayDocument completionHandler:completionHandler];
    }
}

- (void)openDocumentWithContentsOfURLIfClosedAll:(NSDocumentController *)docController
                                     didCloseAll: (BOOL)didCloseAll
                                     contextInfo:(void *)contextInfo
{
    NSDictionary *info = (__bridge NSDictionary *)contextInfo;
    if(self.currentDocument == nil)
        [super openDocumentWithContentsOfURL:[info objectForKey:@"url"] display:YES completionHandler:[info objectForKey:@"completionHandler"]];
}
4

2 に答える 2

1

Apple の cocoa-dev メーリング リストには、目的に合わせてサブクラス化するために何をしなければならないかを説明する非常に有益な情報交換がありNSDocumentControllerます。その結果、新しい文書が開かれると、既存の文書が閉じられます。

他に考えられるのは、ドキュメントのウィンドウがメインから離れる (つまり、NSWindowDidResignMainNotificationウィンドウのデリゲートに送信する) ときにドキュメントの再生をミュートまたは停止することです。

于 2013-03-04T02:12:13.983 に答える