NSFileCoordinator 的长时间延迟 coordinateWritingItemAtURL
Posted
技术标签:
【中文标题】NSFileCoordinator 的长时间延迟 coordinateWritingItemAtURL【英文标题】:Long delay with NSFileCoordinator coordinateWritingItemAtURL 【发布时间】:2015-04-16 15:15:02 【问题描述】:我正在我的应用程序中设置NSFileCoordinator
和NSFilePresenter
,这样我就可以安全地从我的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 NSFileCoordinator
和 NSFilePresenter
说要使用 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...
方法CFReadStreamRef
和CFWriteStreamRef
包装的IO 工作。当让给其他读者/作家时,我并没有做任何昂贵的事情。延迟似乎用于获取用于跨进程协调的任何锁。
@Mr.Jefferson 在写入文件时是否还有其他对象试图处理您的文件?
每个文件有多个文件展示者,是的。但请参阅示例项目。延迟出现在非常简单的示例中。
@Mr.Jefferson 让我检查你的代码然后回复你。
@Mr.Jefferson 我现在无法访问运行 mac OS 的设备,我们可以使用 teamviewer 进行通信吗?我必须看到这段代码在实时环境中运行并调试它。【参考方案2】:
在某些情况下是否可以使用选项NSFileCoordinatorReadingImmediatelyAvailableMetadataOnly
进行阅读和NSFileCoordinatorWritingContentIndependentMetadataOnly
进行写作?看起来这个 ios8 选项可以帮助你。
【讨论】:
以上是关于NSFileCoordinator 的长时间延迟 coordinateWritingItemAtURL的主要内容,如果未能解决你的问题,请参考以下文章
Steaming insert / insertAll - 长时间延迟?
调用 record() 时 AVAudioRecorder 长时间延迟