2013-11-07 2 views
1

Я пытаюсь понять, как использовать флаг события kFSEventStreamEventFlagEventIdsWrapped с FSEvents.Как использовать kFSEventStreamEventFlagEventIdsWrapped с FSEvents?

В соответствии с документацией флаг отправляется зарегистрированным экземплярам, ​​когда счетчик идентификаторов событий обертывается, что делает предыдущий идентификатор события устаревшим.

Теперь давайте представим себе следующий сценарий:

  • зарегистрироваться для FSEvents в моем приложении;
  • По завершении обработки FSEvents (например, мое приложение завершает работу), я сохраняю последний идентификатор события, встречающийся при обработке событий, чтобы иметь возможность воспроизводить изменения с этого идентификатора;
  • Пока мое приложение не работает, счетчик идентификаторов событий обходит вокруг.

Мой вопрос: Как я должен знать, что счетчик обернут? (Таким образом, требуя, чтобы я повторно сканировать всю структуру каталогов.)

ответ

1

У меня теперь есть ответ прямо от Apple.

Сценарий был неправильным для начала. При сохранении последнего обработчика событий вы также должны сохранить с ним UUID потока событий. Идентификатор события действителен только для данного потока событий, который идентифицируется его UUID (см. FSEventsCopyUUIDForDevice()).

Всякий раз, когда счетчик идентификаторов событий обходит вокруг, генерируется новый UUID потока событий. Поэтому, если вы перезапустите приложение после того, как счетчик идентификаторов событий обернут, ваш сохраненный последний идентификатор события больше недействителен, и вы его узнаете, поскольку UUID потока событий будет не таким.

Если вы столкнулись с флагом kFSEventStreamEventFlagEventIdsWrapped, это означает, что счетчик обернут, пока ваше приложение открыто. Однако нет ничего особенного. Вы должны просто убедиться, что вы получили новый UUID потока событий, если хотите сохранить последний идентификатор события.

0

EDIT:

идентификаторы событий не завернуть.

Вот почему: Предположим, что ваша машина генерирует 1 событие файловой системы за миллисекунду. Это означает, что он будет генерировать ms_per_year = 31536000000 событий файловой системы в год. Так что потребуется более 500 миллионов лет, прежде чем счетчик обернется вокруг 64-битной границы.

>>> ms_per_year = 1000*60*60*24*365 
>>> d64 = 2**64 
>>> d64/ms_per_year 
584942417L 
+0

Я знаю, что идентификаторы событий _very_ вряд ли обернутся; вы не отвечаете на вопрос. Я просто пытаюсь понять, как _fully использовать API 'FSEvents'. (Кроме того, если идентификаторы событий не переносятся, зачем создавать флаг 'kFSEventStreamEventFlagEventIdsWrapped'?). Вы сказали в своем ответе перед выпуском, что я не должен сохранять идентификаторы событий на диск. Не могли бы вы уточнить?(Док, кажется, не согласен: «FSEventStreamGetLatestEventId() -> [...] Клиенты могут сохранять это значение постоянно, пока они также сохраняют UUID для устройства»). Спасибо за ваше время. – Frizlab

+0

ну, я думаю, что упакованный флаг есть, потому что какой-то яблочный инженер действительно не понимал огромного пространства из 64-битных целых чисел. возможно, вы * можете * сохранить идентификатор события, но, возможно, он дважды обертывается, а ваше приложение не работает, что вы делаете? я имею в виду действительно, давай, он просто не обертывается. Просто распечатайте несколько идентификаторов событий, они похожи на 123_000_000, на компьютере, который длился годами. Даже если вы нашли способ обработать обкатку идентификаторов событий ... как бы вы ее реалистично протестировали? вы уверены, что инженеры Apple действительно тестировали, действительно ли этот флаг работает? если да, то как они? – Michael

+0

Фактически вы можете сохранить идентификатор события, но вы также должны сохранить UUID потока событий с ним, поскольку идентификатор события действителен только для данного потока событий. UUID потока событий изменяется, когда счетчик обходит вокруг. См. Мой принятый ответ для получения дополнительной информации. – Frizlab

0

Если kFSEventStreamEventFlagEventIdsWrapped установлен, это означает, что 64-битный счетчик событий ID обернутую вокруг. В результате ранее выданные идентификаторы событий больше не являются допустимыми аргументами для параметра afterWhen из функций FSEventStreamCreate(). [1]

В следующий раз вы должны использовать kFSEventStreamEventIdSinceNow для FSEventStreamEventId, и вы должны выполнить повторный сканирование всей директории.

+0

Благодарим за цитирование документации (без ссылки на нее ...), но, как вы можете догадаться, я прочитал документ. Вопрос в том, как узнать счетчик, обернутый вокруг, когда приложение запущено, если оно завершено, когда приложение не было запущено? – Frizlab

+1

@Frizlab Если решение отсутствует в документах, вы должны попробовать fsevent на 2000 экзабайтах памяти и сообщить нам, как использовать этот флаг. –

+0

Если бы я мог! : D В то же время я напрямую прошу Apple, посмотрю, что они говорят об этом :) – Frizlab

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