2016-02-18 5 views
0

Я работаю над подклассом NSDocument. Он представляет текстовый файл в текстовом редакторе.NSDocument представленItemDidChange, вызываемый каждую секунду

Я пытаюсь использовать 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 

Это мой первый раз с помощью этих интерфейсов, поэтому я предполагаю, что я делаю простую ошибку. Если это имеет значение, я запускаю OS X 10.11.3 и Xcode 7.2. Что я делаю не так?

ответ

1

presentedItemDidChange будет называться не только тогда, когда содержимое файла было изменено, но и когда метаданные файла был изменен. И [NSDocument -readFromData:ofType:error:] переписать последнюю открытую дату, одну из метаданных файла, файла.

Итак, это причина, почему presentedItemDidChange был вызван повторно. Если вы хотите обрабатывать обновленные файлы в presentedItemDidChange, вам обычно необходимо определить, что было изменено вначале.

cf. NSFilePresenter Protocol Reference

0

Оказалось, что мне это не нужно. [NSDocument -readFromData:ofType:error:] вызывается автоматически при изменении файла, поэтому я просто обновляю пользовательский интерфейс с новыми данными при его вызове. Я ошибочно думал, что этот метод был вызван только один раз, во время инициализации.

(я до сих пор не знаю, почему presentedItemDidChange называли неоднократно.)

+0

Вы установили что-нибудь так: 'readFromData: ofType: error:' вызывается? Я попытался воспроизвести это, но вызывается только 'presentationItemDidChange' (я также делегирую' super'). Это называется один раз, хотя, не каждую секунду. Я подозреваю, что это нечто несвязанное, что вызывает изменения. – ctietze

Смежные вопросы