如何将我的异步URL图像按顺序加载到NSMutableArray中?

时间:2015-04-28 13:59:52

标签: ios objective-c nsmutablearray

我正在尝试按照网址加载图片,并将它们按顺序存储在NSMutableArray 。如果我不关心按顺序存储图像,我当前的代码是否正常工作,但它不按顺序存储它们。它目前根据异步请求的完成速度将图像存储在 articleImage 数组中。我试过使用insertObject:AtIndex,但无法使用任何东西。为了澄清,我试图以(有序的方式)存储图像的NSMutableArray是 articleImage

以下是我的viewDidLoad中的一些代码:

dispatch_async(dispatch_get_main_queue(), ^{

                    if(articleInfoJSONArray.count > 0)
                    {
                        for(int i=0; i<articleInfoJSONArray.count; i++)
                        {
                            [issueID addObject:[[articleInfoJSONArray objectAtIndex:i] objectForKey:@"issueID"]];
                            [articleID addObject:[[articleInfoJSONArray objectAtIndex:i] objectForKey:@"articleID"]];


                            NSString *imageLink = [[articleInfoJSONArray objectAtIndex:i] objectForKey:@"articleImage"];

                            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

                            dispatch_async(queue, ^{

                                NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageLink]];
                                UIImage *image = [UIImage imageWithData:data];

                                dispatch_async(dispatch_get_main_queue(), ^{

                                    [articleImage addObject:image];
                                    if(articleImage.count == articleInfoJSONArray.count)
                                        [self imagesLoaded];
                                });
                            });
                        }
                    }                        
                });

这是我的图片已加载:

- (void)imagesLoaded
{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
    ViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"MainView"];
    [self presentViewController:vc animated:NO completion:nil];

}

3 个答案:

答案 0 :(得分:0)

我进行图像下载的一种方法是使用NSOperationQueue和NSOperation。您可以在头文件中定义NSOperationQueue:

@property (strong, nonatomic) NSOperationQueue *sequentialOperationQueue;

在您的实施中执行:

self.sequentialOperationQueue = [[NSOperationQueue alloc] init];
self.sequentialOperationQueue.maxConcurrentOperationCount = 1;

然后你可以添加:

for (NSDictionary *imageDict in imagesToFetch) {
    ImageDownloadOperation *imgDownloadOperation = [[ImageDownloadOperation alloc] initWithImageLocationDict:imageDict];
    [self.sequentialOperationQueue addOperation:imgDownloadOperation];
}

LogoDownloadOperation是NSOperation的子类。这样,您始终只有一个活动下载并按您想要的顺序处理它们。有关NSOperation的详细信息,请查看apple doc。

我在ImageDownloadOperation中的

提取:

- (void)start {
    NSURL *imageUrl = [NSURL URLWithString:self.imageDict[@"imageUrl"]];

    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];

    NSURLSessionDownloadTask *downloadPhotoTask = [session
                                               downloadTaskWithURL:imageUrl
                                               completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {

                                                   if (error) {
                                                       self.sessionTask = nil;


                                                       [self done];


                                                       return;
                                                   }




                                                   NSData *imageData = [NSData dataWithContentsOfURL:location];
                                                   NSBlockOperation *saveImageBlockOperation = [NSBlockOperation blockOperationWithBlock:^{
                                                       [SharedAppDelegate.entityManager saveImage:imageData
                                                                                            imageDict:self.imageDict
                                                                                  inManagedObjectContext:SharedAppDelegate.managedObjectContext];
                                                   }];
                                                   saveImageBlockOperation.qualityOfService = NSQualityOfServiceBackground;
                                                   [[NSOperationQueue mainQueue] addOperation:saveImageBlockOperation];


                                                   [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
                                                   self.sessionTask = nil;
                                                   [self done];
                                               }];


    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}

如您所见,我通过我的AppDelegate在CoreData中存储imageData。而不是我的方式,你可以给ImageDownloadOperation一个指向你的NSMutableArray的指针,然后你可以直接将数据存储在你的数组中。

答案 1 :(得分:0)

尝试使用dispatch_group。调度组监视已添加到其中的工作,并且它将知道该工作何时完成。 :) http://commandshift.co.uk/blog/2014/03/19/using-dispatch-groups-to-wait-for-multiple-web-services/

答案 2 :(得分:0)

任务完成后,您可以创建[UIImage new]数组 替换空图像images[i] = newImage

修改

NSMutableArray *imageArray = [NSMutableArray new];

for (int i=0; i<articleInfoJSONArray.count; i++) {
    [imageArray addObject:[UIImage new]];
}

for (int i=0; i<articleInfoJSONArray.count; i++) {
    dispatch_async(dispatch_get_main_queue(), ^{
        //download image
        imageArray[i] = downloadedImage;
    });
}