使用GCD将图像异步加载到阵列

时间:2014-07-21 08:52:40

标签: ios objective-c arrays grand-central-dispatch

我尝试使用panoramaGL框架来显示全景图。服务器端为多维数据集全景图的每一侧返回多个平铺图像。所以我需要将这些图像异步加载到数组中,然后我需要从这个图像中制作一个大的边纹理 - 这个任务的第一部分的代码是:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

    int columnCount;
    int rowCount;

    NSString *side;

    if ([level  isEqual: @"3"]) {
        columnCount = 1;
        rowCount = 1;
    } else if ([level  isEqual: @"2"]) {
        columnCount = 2;
        rowCount = 2;

...这里我准备了url字符串参数

    if (face == PLCubeFaceOrientationFront)
        side = @"F";
    else if (face == PLCubeFaceOrientationBack)
        side = @"B";

...这里我准备了url字符串参数

    self.tileArray = [[NSMutableArray alloc] initWithCapacity:columnCount];

    for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
        for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {

            NSString *tileUrl = [NSString stringWithFormat:@"%d_%d", columnIndex, rowIndex];

            NSMutableArray *tileUrlComponents = [NSMutableArray array];

            [tileUrlComponents addObject: panoramaData[@"id"]];
            [tileUrlComponents addObject: side];
            [tileUrlComponents addObject: level];
            [tileUrlComponents addObject: tileUrl];

            NSString *tileIdString = [tileUrlComponents componentsJoinedByString:@"/"];

            NSString *panoramaIdUrlString = [NSString stringWithFormat:@"http://SOMEURL=%@", tileIdString];

            NSURL *url = [NSURL URLWithString:panoramaIdUrlString];
            NSURLRequest *req = [NSURLRequest requestWithURL:url];

            [NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *res, NSData *data, NSError *err) {
                UIImage *image = [UIImage imageWithData:data];
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSMutableArray *array = [self.tileArray objectAtIndex:columnIndex];
                    [array replaceObjectAtIndex:rowIndex withObject:image];
                    [self.tileArray addObject:array];
                });
            }];

            NSLog(@"The URL for the %@ tile is %@", tileUrl, tileIdString);
        }
    }
});

主要问题 - 我怎么能理解,我的数组已加载 - 我现在可以处理其中的图像了。第二个问题是我现在不幸地得到了空数组。有什么帮助吗?

2 个答案:

答案 0 :(得分:0)

我不确定您是否考虑过使用操作。

我会这样做:

  1. 为每个请求创建NSOperation(确保代码中的操作保持活动状态,直到完成加载)
  2. 将每个操作添加到NSOperationQueue。 (通过调用-operations,您可以看到正在进行的操作数量)
  3. 如果在反向线程上实现NSOperationQueue,则可以使用-waitUntilAllOperationsAreFinished(此方法阻止当前线程直到所有图像都已下载),然后执行代码以显示图像。您也可以将所有NSOperation's添加到NSArray,然后使用NSOperationQueue
  4. 添加到-(void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait

答案 1 :(得分:0)

你可以做这样的事情

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0ul);         dispatch_async(queue,^ {

        dispatch_sync(dispatch_get_main_queue(), ^{

            NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
            UIImage *image = [[UIImage alloc] initWithData: data];


            [UIImageJPEGRepresentation(image, 100) writeToFile: imagePath atomically: YES];


        });
    });

其中imagePath是应用程序目录中的路径。您可以创建一个临时目录并将图像存储在那里......在检索时,您只需使用简单方法即可。

UIImage * image = [UIImage imageWithCOntentsOFFile:imagePath];。

它对我有用......只是试一试