1

在这里粗略地通过 GCD 安排磁盘读取。

下面是一个代码片段,用于从包含 about 帧的文件中加载frameCount=1000帧。在我最初的实现中,我从主线程执行此操作:

[self readFramesFromFrame:0 toFrame:frameCount];

这是我的方法:

-(BOOL)readFramesFromFrame:(NSInteger)startFrame toFrame:(NSInteger)endFrame

{
    if (frameCount<=0)
        return YES;

    __block BOOL endRead;

    dispatch_async(diskQueue, ^{
        do {
            dispatch_async(frameQueue, ^{
                for (NSInteger i=startFrame; i<endFrame; i++)
                    [self readFileFrame:i];
            });

            // ** BEGIN get next batch
            NSInteger newStart = endFrame;
            NSInteger newEnd = ((endFrame+highWater) < frameCount) ? endFrame+highWater : frameCount;

            if (newStart==frameCount)
                endRead=YES;
            else
                endRead=[self readFramesFromFrame:(NSInteger)newStart toFrame:(NSInteger)newEnd];
            // ** END get next batch

        } while (!endRead);
    });

    return YES;
}

但是,我不想加载 1000 帧的初始运行,因为它需要太长时间。

我最初只想加载 20 帧(我的高水位量),所以我重新调整了代码并进行了修改后的调用:

[self readFramesFromFrame:0 toFrame:(frameCount<highWater) ? frameCount : highWater];

但这仍然需要很长时间才能访问第一帧进行处理。我正在尝试安排单独的工作块而不是一大块工作,但我意识到我仍在有效地安排所有帧。没提升。

两点解释。首先,我调用[self readFileFrame:frameNumber]adispatch_io_read使用 a readQueue,我的下游处理处理程序在其他地方通过调用dispatch_suspend(readQueue)or来限制它dispatch_resume(readQueue)。我使用 10 帧的低水位值和 20 帧的高水位值,它们会readQueue酌情暂停/恢复。这运行得很好,但目前基于合理的帧队列。

其次,我的调用将通过一个单独的 GCD 计时器访问(和显示)readFileFrame的线程产生一个有效的数据帧。readQueue

我已经尝试在主队列上的“下一批”评论之间分派代码片段,但这也是一场灾难。我认为添加一个额外的包装串行私有队列frameQueue会有所帮助,但没有。

如果我假设它frameCount是 50 帧,那么事情会非常快速且流畅地运行——但我只得到 50 帧,仅此而已。

如何重新调整此代码片段,以便它懒惰地读取成批的帧?

4

0 回答 0