如何将我的异步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];
}
一种方法我做的图像下载是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/
不要发布链接,请解释如何实现这一目标,因为未来链接可能会中断。 –
你可以做的[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;
});
}
我不遵循:( –
我编辑了我的帖子,更详细 – Halpo
不看代码的话“异步”和“秩序“似乎相互排斥。 – *foe
希望情况并非如此:( –
再一次,没有看代码,我可以想到2个解决方案:1.一个后台线程按顺序加载图像2.将索引号与每个作业相关联并使用它来存储图片在他们的阵列中,1更好,因为它更简单,并且可能运行得更快 – *foe