如何将我的异步url映像加载到NSMutableArray中?

问题描述:

我试图通过它们的URL加载图像并将它们按照的顺序存储在NSMutableArray 中。如果我不关心按顺序存储图像,我的当前代码正常工作,但是它存储的顺序不是这样。它目前根据异步请求完成的速度将图像存储在articleImage数组中。我试图玩弄insertObject:AtIndex,但无法取得任何工作。为了澄清,我试图存储图像(以有序的方式)的NSMutableArray是articleImage如何将我的异步url映像加载到NSMutableArray中?

这里是我的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]; 
           }); 
          }); 
         } 
        }       
       }); 

这里是我的imagesLoaded:

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

} 
+0

不看代码的话“异步”和“秩序“似乎相互排斥。 – *foe

+0

希望情况并非如此:( –

+0

再一次,没有看代码,我可以想到2个解决方案:1.一个后台线程按顺序加载图像2.将索引号与每个作业相关联并使用它来存储图片在他们的阵列中,1更好,因为它更简单,并且可能运行得更快 – *foe

一种方法我做的图像下载是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文档。

中提取我的确在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; 
} 

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

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

+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; 
    }); 
} 
+0

我不遵循:( –

+0

我编辑了我的帖子,更详细 – Halpo