在我的游戏中,按下“播放”按钮后,将显示游戏视图控制器,并且资产开始在后台预加载几个资产,供以后在游戏中使用。

我的问题是,当按下主页按钮但我的预加载过程仍在运行时,如何停止预加载过程?

现在,我必须等到所有预加载完成后才能进行适当的分配...

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/

10-09 02:20