首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将NSDocumentController子类化为一次只允许一个文档

如何将NSDocumentController子类化为一次只允许一个文档
EN

Stack Overflow用户
提问于 2013-03-04 09:26:23
回答 2查看 1.4K关注 0票数 1

我正在尝试创建一个Core Data,基于文档的应用程序,但有一个限制,一次只能查看一个文档(这是一个音频应用程序,很多文档同时发出噪音是没有意义的)。

我的计划是以一种不需要将其链接到任何菜单操作的方式对NSDocumentController进行子类化。这是合理的,但我遇到了一个问题,这让我对我的方法产生了一些疑问。

下面的代码在大多数情况下都有效,除非用户执行以下操作:-尝试打开一个打开了现有“脏”文档的文档-单击保存/不保存/取消警报中的取消(此操作正常)-然后再次尝试打开文档。由于某些原因,现在openDocumentWithContentsOfURL方法再也不会被调用了,即使出现了打开对话框。

有人能帮我找出原因吗?或者给我举个例子,告诉我怎么做才对?它看起来像是一些人实现的东西,但是我找不到10.7+的例子。

代码语言:javascript
复制
- (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"]];
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-04 10:12:14

Apple's cocoa-dev mailing list上有一个内容非常丰富的交流,它描述了为了实现您的目的而对NSDocumentController进行子类所必须做的事情。其结果是,当打开新文档时,现有文档将被关闭。

您可以考虑的其他事情是,当文档的窗口放弃main (即,将NSWindowDidResignMainNotification发送给窗口的委派)时,将其静音或停止播放,即使只是为了避免对用户施加似乎是人为的限制。

票数 1
EN

Stack Overflow用户

发布于 2017-08-29 13:08:55

我知道已经有一段时间了,但以防它能帮助其他人...

我有一个我认为是类似的问题,解决方案是当我的自定义DocumentController没有打开文档时调用完成处理程序,例如:

代码语言:javascript
复制
- (void)openDocumentWithContentsOfURL:(NSURL *)url display:(BOOL)displayDocument completionHandler:(void (^)(NSDocument * _Nullable, BOOL, NSError * _Nullable))completionHandler {

    if (doOpenDocument) {
        [super openDocumentWithContentsOfURL:url display:displayDocument completionHandler:completionHandler];
    } else {
        completionHandler(NULL, NO, NULL);
    }
}

当我添加completionHandler(NULL, NO, NULL);时,它开始工作不止一次。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15193136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档