粗略地通过GCD安排磁盘读取。
以下是从包含大约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]
的调用使用dispatch_io_read
执行readQueue
,我的下游处理处理程序通过调用dispatch_suspend(readQueue)
或dispatch_resume(readQueue)
来限制其他地方。我使用10帧的低水位值和20帧的高水位值,根据需要暂停/恢复readQueue
。这在游泳方面运作良好,但目前基于一个合理的框架队列。
其次,我对readFileFrame
的调用将通过readQueue
线程生成一个有效的数据帧,该线程通过单独的GCD计时器访问(并显示)。
我已经尝试在主队列上的“下一批”评论之间调度代码片段,但这也是一场灾难。我认为添加一个额外的包装序列私有队列frameQueue
会有所帮助,但没有。
如果我假装frameCount
是50帧,那么事情很快就能很好地运行 - 但我只能获得50帧而不是更多。
如何重新设置此代码段以便懒散地读取多批帧?