gpt4 book ai didi

ios - 使用 GCD 复制文件的最有效方法?

转载 作者:技术小花猫 更新时间:2023-10-29 11:22:08 24 4
gpt4 key购买 nike

借助 Grand Central Dispatch,您可以安排读取和写入,而无需过多担心何时/如何发生。与我之前基于 NSStream 的方法相比,这需要更少的外部管理。但是,我天真的实现比基于 NSStream 的方法慢。

对于 NSStream,我查询了源和目标的首选 IO 大小 (NSURLPreferredIOBlockSizeKey)。然后我将整个“首选输入大小的 block ”读入缓冲区,一旦缓冲区中至少有“首选输出大小”字节,我就将整个 block 写入目的地(当然,最后一个 block 除外)。这应该非常接近读写性能的最佳值。

不过,有了GCD,我对此影响不大。想象一下,源的首选 IO 大小为 100kB,目标的首选 IO 大小为 1MB:我的原始实现现在的写入频率是基于 NSStream 的解决方案中的 10 倍。

那么,用 GCD 解决这个问题的最有效方法是什么?简单地写入读取器 block 中的缓冲区,一旦收集到足够的数据,就安排一个“首选输出大小”的写入 block ?我想 GCD 可能会在这里为我提供一个我还不知道的解决方案。

这是我目前的 GCD 解决方案中最重要的部分:

// input_ and output_ are of type dispatch_io_t

dispatch_io_read(
input_,
0,
SIZE_MAX,
dispatch_get_main_queue(),
^(bool done, dispatch_data_t data, int error) {
size_t data_size;

if (error) {
NSLog(@"Input: error %d", error);
[self cancel];
return;
}
if (data) {
data_size = dispatch_data_get_size(data);
if (data_size > 0) {
dispatch_io_write(
output_,
0,
data,
dispatch_get_main_queue(), ^(bool done, dispatch_data_t data, int error) {
// TODO: I don't know how to get the offset (for progress). So I need to
// pass it from the calling block.
if (error) {
NSLog(@"Output: error %d", error);
return;
}
if (done) {
bytesWritten_ += data_size;
// Update progress report here.
}
}
);
}
}
}
);

最佳答案

虽然在大多数情况下没有必要,但您可以通过 dispatch_io_set_high_water(3)dispatch_io_set_low_water(3) API 影响 GCD 使用的 IO 大小。

GCD 不会读取或写入大于 channel 高水位线的 block 。也永远不会使用小于低水位线的数据对象调用读/写处理程序。

例如通过将示例中 input_ 的低水位线设置为 1MB,您可以确保当前读取回调不会将小于 1MB 的数据对象传递给 dispatch_io_write(3)

如果此控件不能满足您的情况,您还可以组合通过 dispatch_data_create_concat(3) 连续调用读取处理程序接收到的多个数据对象,直到它们达到足够大以通过到 dispatch_io_write(3)

希望这不是必需的,但是,将源端的低水位线设置为首选源 block 大小的倍数,该大小足以达到首选目标 block 大小,并将目标 channel 的高水位线设置为首选目标 block 大小(或其倍数)应该为您提供与当前基于 NSStream 的解决方案相同的性能。

您可以在 implementation 中查看 GCD IO 缓冲策略的细节。 .

无论如何,请务必提交 bug与您看到默认 GCD IO 缓冲性能问题的任何情况的细节。

关于ios - 使用 GCD 复制文件的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9633355/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com