在这里粗略地通过 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 帧,仅此而已。
如何重新调整此代码片段,以便它懒惰地读取成批的帧?