NSDocument presentItemDidChange每秒调用一次

时间:2016-02-18 04:50:19

标签: objective-c macos nsdocument nsfilecoordinator

我正在研究NSDocument子类。它表示文本编辑器中的文本文件。

我正在尝试使用the NSFilePresenter protocol来响应其他应用程序所做的更改(例如,如果用户在此处打开同一文件时保存TextEdit中的更改)。

我目前的实施方式是这样......

我为文件协调员添加了一个属性:

@property (nonatomic) NSFileCoordinator *fileCoordinator;

我懒洋洋地创造它:

- (NSFileCoordinator *) fileCoordinator {
    if (!_fileCoordinator) {
        [NSFileCoordinator addFilePresenter:self];
        _fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:self];
    }

    return _fileCoordinator;
}

调用presentedItemDidChange时,我从磁盘重新加载文件并显示它:

- (void)presentedItemDidChange {
    [super presentedItemDidChange];

    NSLog(@"presentedItemDidChange was called");

    if (self.presentedItemURL.isFileURL && self.fileType) {
        NSError *coordinatorError = nil;

        [self.fileCoordinator coordinateReadingItemAtURL:self.presentedItemURL options:NSFileCoordinatorReadingWithoutChanges error:&coordinatorError byAccessor:^(NSURL *newURL) {
            NSError *readError = nil;
            [self readFromURL:newURL ofType:self.fileType error:&readError];
            if (readError) NSLog(@"%@", readError);
        }];

        if (coordinatorError) NSLog(@"%@", coordinatorError);

        [self reloadString];
    }
}

此代码有效:当我在TextEdit中保存文件时,更改会显示在我的应用程序中。

但是,保存此文件后,会重复调用presentedItemDidChange(大约每秒一次)。几分钟后,应用程序因内存错误而崩溃。没有记录错误;控制台看起来基本上是这样的:

2016-02-17 22:43:46.233 MacDown[66847:2470964] presentedItemDidChange was called
2016-02-17 22:43:51.721 MacDown[66847:2470960] presentedItemDidChange was called
2016-02-17 22:43:52.816 MacDown[66847:2471206] presentedItemDidChange was called
2016-02-17 22:43:53.819 MacDown[66847:2470964] presentedItemDidChange was called
2016-02-17 22:43:54.920 MacDown[66847:2471206] presentedItemDidChange was called
2016-02-17 22:43:56.014 MacDown[66847:2470964] presentedItemDidChange was called
2016-02-17 22:43:57.115 MacDown[66847:2471206] presentedItemDidChange was called
2016-02-17 22:43:58.117 MacDown[66847:2470964] presentedItemDidChange was called

这是我第一次使用这些API,所以我假设我犯了一个简单的错误。如果重要,我正在运行OS X 10.11.3和Xcode 7.2。我做错了什么?

2 个答案:

答案 0 :(得分:1)

presentedItemDidChange不仅会在文件内容发生更改时调用,而且还会在文件元数据发生更改时调用。 [NSDocument -readFromData:ofType:error:]覆盖文件的最后一个打开日期,即文件元数据之一。

所以,这就是重复调用presentedItemDidChange的原因。如果要处理presentedItemDidChange中的更新文件,通常需要先确定更改的内容。

比照NSFilePresenter Protocol Reference

答案 1 :(得分:0)

事实证明我不需要任何这些。文件更改时会自动调用[NSDocument -readFromData:ofType:error:],因此我只需在调用时使用新数据更新UI。我错误地认为这个方法在初始化期间只被调用一次。

(我仍然不确定为什么presentedItemDidChange被重复调用。)