0

在我的游戏中,按下播放按钮后,会显示游戏视图控制器,并且一些资源开始在后台预加载以供以后在游戏中使用。

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

现在我必须等到所有预加载完成才能正确解除分配......

视图控制器.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];
    });

SpaceSun, 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;
}
4

1 回答 1

1

您无法取消已使用 dispatch_async 安排的块。而不是使用 GCD,您应该更喜欢更高级别的NSOperationAPI。为您的任务创建多个 NSOperation 子类并将它们安排在NSOperationQueue.

如果您有需要比其他任务更早完成的任务,请使用addDependency:.

要取消预加载过程,只需调用:

[self.operationQueue cancelAllOperations];

为了从操作队列公开的取消功能中受益,您应该定期检查该isCancelled属性以获取更长时间运行的操作:

- (void)main
{

  for (int i = 0; i < _imageCount; i++) {

     if (self.isCancelled) break;

     // do your processing

  }
}
于 2013-10-28T12:51:11.263 回答