在我的游戏中,按下“播放”按钮后,将显示游戏视图控制器,并且资产开始在后台预加载几个资产,供以后在游戏中使用。
我的问题是,当按下主页按钮但我的预加载过程仍在运行时,如何停止预加载过程?
现在,我必须等到所有预加载完成后才能进行适当的分配...
ViewController.m
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
// preload intro sequences
dispatch_sync(concurrentQueue, ^{
[weak_self.spaceSun prepareAnimationArrays];
});
dispatch_async(concurrentQueue, ^{
[weak_self.sailor prepareAnimationArrays];
});
太空太阳,Sailor.m
- (void)prepareAnimationArrays
{
_introArray = [NSMutableArray new];
_introArray = [self.animator generateCachedImageArrayWithFilename:@"circleSun" extension:@".png" andImageCount:10];
self.isAnimationArrayCached = YES;
}
- (NSMutableArray *)generateCachedLoopedImageArrayWithFilename:(NSString *)filename
extension:
(NSString *)extension
andImageCount:
(int)count
{
_imagesArray = [[NSMutableArray alloc] init];
_fileExtension = extension;
_animationImageName = filename;
_imageCount = count;
for (int i = 0; i < _imageCount; i++)
{
NSString *tempImageName = [NSString stringWithFormat:@"%@%i", filename, i];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:tempImageName ofType:extension];
UIImage *frameImage = [self loadRetinaImageIfAvailable:imagePath];
UIGraphicsBeginImageContextWithOptions(frameImage.size, NO, [UIScreen mainScreen].scale);
CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
[frameImage drawInRect:rect];
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[_imagesArray addObject:renderedImage];
_precachedImagesCount++;
if (_didPreCachePicture)
_didPreCachePicture();
if (_isDoublingFrames)
{
[_imagesArray addObject:renderedImage];
}
else if (_isTriplingFrames)
{
[_imagesArray addObject:renderedImage];
[_imagesArray addObject:renderedImage];
}
if (i == _imageCount - 1)
{
// we have 5 images
// 12345 already in array
// let's add 432
for (int j = _imageCount - 2; j > 0; j--)
{
tempImageName = [NSString stringWithFormat:@"%@%i", filename, j];
imagePath = [[NSBundle mainBundle] pathForResource:tempImageName ofType:extension];
frameImage = [self loadRetinaImageIfAvailable:imagePath];
UIGraphicsBeginImageContextWithOptions(frameImage.size, NO, [UIScreen mainScreen].scale);
rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
[frameImage drawInRect:rect];
renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[_imagesArray addObject:renderedImage];
_precachedImagesCount++;
if (_didPreCachePicture)
_didPreCachePicture();
if (_isDoublingFrames)
{
[_imagesArray addObject:renderedImage];
}
else if (_isTriplingFrames)
{
[_imagesArray addObject:renderedImage];
[_imagesArray addObject:renderedImage];
}
}
}
}
return _imagesArray;
}
最佳答案
您不能取消已使用dispatch_async调度的块。而不是使用GCD,您应该使用更高级别的NSOperation
API。为您的任务创建多个NSOperation子类,并将它们安排在NSOperationQueue
上。
如果您有需要比其他任务更早完成的任务,请使用addDependency:
指定操作之间的依赖关系。
要取消预加载过程,只需调用:
[self.operationQueue cancelAllOperations];
为了从操作队列公开的取消功能中受益,您应该定期检查
isCancelled
属性以查找运行时间更长的操作:- (void)main
{
for (int i = 0; i < _imageCount; i++) {
if (self.isCancelled) break;
// do your processing
}
}
关于ios - 如何停止在并发线程中运行的预加载进程?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19634492/