NSFileCoordinator 的长时间延迟 coordinateWritingItemAtURL

Posted

技术标签:

【中文标题】NSFileCoordinator 的长时间延迟 coordinateWritingItemAtURL【英文标题】:Long delay with NSFileCoordinator coordinateWritingItemAtURL 【发布时间】:2015-04-16 15:15:02 【问题描述】:

我正在我的应用程序中设置NSFileCoordinatorNSFilePresenter,这样我就可以安全地从我的AppleWatch 应用程序执行文件IO。在我的代码中有一些地方我会快速连续多次写入文件。这本身就是一个问题,我正在努力纠正它,但我注意到这个过程中有一些奇怪的行为。

我这样包装我的文章:

//In a class that implements NSFilePresenter:
NSFileCoordinator *coord = [[NSFileCoordinator alloc]initWithFilePresenter:self];
[coord coordinateWritingItemAtURL:self.presentedItemUrl options:0 error:nil byAccessor:^(NSURL *url)

  //do my writing here using CFWriteStreamRef or NSOutputStream
];

在第一次写入时,写入块发生在 1 毫秒内。但在那之后,调用coordinateWritingItemAtURL 和执行写入块之间大约有0.5 秒的延迟。

这是预期的行为吗?

Some of the documentation for NSFileCoordinatorNSFilePresenter 说要使用 prepareForReadingItemsAtURLs:writingItemsAtURLs:options:error:byAccessor: 进行批处理操作,但是当我不批处理时延迟这么长似乎很奇怪。

更新:阅读也会发生这种情况。

更新 2:Here 是重现问题的示例项目。

更新 3: 使用此 API 在应用程序与其扩展程序之间进行协调是 apparently 和 bad idea。但问题仍然存在。

【问题讨论】:

你从哪里调用坐标写...手表扩展,通过 openParentApplication 的父应用程序,其他地方......? @MattG 在父应用程序中。 在错误字段中传递一个有效的 NSError 对象,以查看您在第一次写入时是否收到任何错误(也许这就是它立即返回的原因)。除此之外,通常,块不会立即执行,它们的行为是异步的,可以在运行循环中稍后执行。 我总是传递一个错误,并且永远不会得到任何回报。 【参考方案1】:

参考 File System Programming Guide ,您可以阅读以下内容:

您可能希望避免直接从文件中合并更改 演示者方法。相反,将块异步分派到 调度队列并在以后处理更改。这让你 在您的应用方便时处理更改,而不会导致 对发起更改的文件协调员造成了不必要的延迟。 当然,当保存或放弃对文件的控制时(例如在 relinquishPresentedItemToReader:, relinquishPresentedItemToWriter:, 或 savePresentedItemChangesWithCompletionHandler:方法)你应该 立即执行所有必要的操作,而不是推迟

我认为这是您推迟行动的情况。

可能的解决方案:

请好好阅读this,正确处理多次连续的写入操作,relinquishPresentedItemToWriter,可以胜任,读取文件也一样,relinquishPresentedItemToReader ,假设多个不同的对象正在尝试读取和写入同一个文件。

附注:

我不知道你的应用到底是做什么的,但我希望你已经阅读了这篇文章:

如果您正在实施基于文档的应用程序,则无需 将文件呈现器语义合并到您的 NSDocument 子类中。 NSDocument 类已经符合 NSFilePresenter 协议 并实施适当的方法。因此,您的所有文件 自动将自己注册为相应的演示者 文件并执行诸如保存更改和跟踪更改 文件。

【讨论】:

我没有使用 NSDocument。由coordinate... 方法CFReadStreamRefCFWriteStreamRef 包装的IO 工作。当让给其他读者/作家时,我并没有做任何昂贵的事情。延迟似乎用于获取用于跨进程协调的任何锁。 @Mr.Jefferson 在写入文件时是否还有其他对象试图处理您的文件? 每个文件有多个文件展示者,是的。但请参阅示例项目。延迟出现在非常简单的示例中。 @Mr.Jefferson 让我检查你的代码然后回复你。 @Mr.Jefferson 我现在无法访问运行 mac OS 的设备,我们可以使用 teamviewer 进行通信吗?我必须看到这段代码在实时环境中运行并调试它。【参考方案2】:

在某些情况下是否可以使用选项NSFileCoordinatorReadingImmediatelyAvailableMetadataOnly 进行阅读和NSFileCoordinatorWritingContentIndependentMetadataOnly 进行写作?看起来这个 ios8 选项可以帮助你。

【讨论】:

以上是关于NSFileCoordinator 的长时间延迟 coordinateWritingItemAtURL的主要内容,如果未能解决你的问题,请参考以下文章

偶尔会遇到长时间的垃圾收集延迟,为啥?

Steaming insert / insertAll - 长时间延迟?

调用 record() 时 AVAudioRecorder 长时间延迟

使用 wordpress 加载文档的长时间延迟

Qt QNetworkAccessManager 发出完成信号的长时间延迟

延迟长时间运行的计时器任务以提高滚动平滑度