ios - 如何停止在并发线程中运行的预加载进程?

标签 ios objective-c concurrency

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

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

现在我必须等到所有预加载完成才能正确释放...

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];
    });

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;
}

最佳答案

您无法取消使用dispatch_async调度的 block 。您应该更喜欢使用更高级别的 NSOperation API,而不是使用 GCD。为您的任务创建多个 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/

相关文章:

ios - 将单元格的高度设置为等于标签内容

ios - Objective-C - #define 使用 __VA_ARGS__

ios - 适当的 AutoresizingMask

ios - didFinishLaunchingwithOptions 在 awakeFromNib 之后调用

ios - react native : Could not connect to development server

objective-c - 我如何从 object_getIvar(self, myIntVar) 获取 int 值,因为它返回一个指针

java - 在 Java 6 中用于并发访问列表的最佳方法

c# - .NET ConcurrentDictionary 初始容量设置为任意质数,而不是 MSDN 示例文档中的预期容量。为什么?

ios - 计算属性 - 如何仅在主线程上使用?