Ios dataWithContentsOfURL与downloadTaskWithURL
当我使用从另一个web服务检索的url获取图像数据,并且需要更新模型对象时,更新相应的视图总是有问题。基本上,问题是:Ios dataWithContentsOfURL与downloadTaskWithURL,ios,ios7,Ios,Ios7,当我使用从另一个web服务检索的url获取图像数据,并且需要更新模型对象时,更新相应的视图总是有问题。基本上,问题是: 将Web服务称为 检索图像URL-第一次调用返回块 使用图像URL调用Web服务 检索图像数据 使用图像数据更新模型对象 基于模型对象更新视图对象缩略图(例如:uicollectionviewcell或uitableviewcell)(此处出现问题) 我以前在AFNetworking和相应的NSURLSession中使用过这种方法。但是,问题是,在更新模型对象之后,我需要在缩略
- (void)searchFlickrForTerm:(NSString *) term completionBlock:(FlickrSearchCompletionBlock) completionBlock
{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:config
delegate:self
delegateQueue:nil];
NSString *requestString = [Flickr flickrSearchURLForSearchTerm:term];
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if (error != nil) {
completionBlock(term,nil,error);
}
else{
NSDictionary *searchResultsDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
//This is the segment where we parse the Flickr data
NSString * status = searchResultsDict[@"stat"];
if ([status isEqualToString:@"fail"]) {
NSError * error = [[NSError alloc] initWithDomain:@"FlickrSearch" code:0 userInfo:@{NSLocalizedFailureReasonErrorKey: searchResultsDict[@"message"]}];
completionBlock(term, nil, error);
} else {
NSArray *objPhotos = searchResultsDict[@"photos"][@"photo"];
NSMutableArray *flickrPhotos = [@[] mutableCopy];
for(NSMutableDictionary *objPhoto in objPhotos)
{
//Good Idea to parse in the web service call itself. The structure might be different
//If parse in the model class, can be very complicated if the structure is different
FlickrPhoto *photo = [[FlickrPhoto alloc] init];
photo.farm = [objPhoto[@"farm"] intValue];
photo.server = [objPhoto[@"server"] intValue];
photo.secret = objPhoto[@"secret"];
photo.photoID = [objPhoto[@"id"] longLongValue];
NSString *searchURL = [Flickr flickrPhotoURLForFlickrPhoto:photo size:@"m"];
//Call to retrieve image data
NSURLSessionDownloadTask *getImageTask = [_session downloadTaskWithURL:[NSURL URLWithString:searchURL] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){
UIImage *downloadImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
photo.thumbnail = downloadImage;
}];
[getImageTask resume];
[flickrPhotos addObject:photo];
}
completionBlock(term,flickrPhotos,nil);
}
//End parse of Flickr Data
}
}];
[dataTask resume];
//End
}
在上面的代码段中,在解析FlickrPhoto模型对象之后,我使用NSURLDownloadTask调用图像的url。这是有问题的代码段
方法A:
NSURLSessionDownloadTask *getImageTask = [_session downloadTaskWithURL:[NSURL URLWithString:searchURL] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){
UIImage *downloadImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
photo.thumbnail = downloadImage;
}];
[getImageTask resume];
但是,如前所述,即使在我更新了photo.缩略图属性之后,在我的uicollectionview中,我将imageView设置为从缩略图属性读取,图像也不会显示在我的集合视图上,除非我滚动
然而,有趣的是,我没有使用NSURLDownloadTask,而是使用dataWithContentsOfURL,图像显示时不需要滚动集合视图
方法B:
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:searchURL]
options:0
error:&error];
UIImage *image = [UIImage imageWithData:imageData];
photo.thumbnail = image;
我不知道为什么会这样。我还通过抓取视图控制器中的主线程来重新加载集合视图数据
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
});
我真的为这篇冗长的帖子道歉,但如果有人能给我提供建议,我将不胜感激。我已经阅读了文档,但我仍然能够找到这个令人困惑的问题的有意义的答案 好吧,在仔细研究了苹果的文档之后,我想我知道了这个问题 本质上,在我的方法中,downloadTaskWithURL将派生出另一个后台线程。因此,即使我已经更新了模型对象,视图也不会用新信息更新,除非我再次抓取主线程并刷新视图 然而,在方法B中,dataWithContentsOfURL同步运行。因此,根本不存在背景线程的问题 来自apple文档: dataWithContentsOfURL: 返回包含给定URL指定位置的数据的数据对象 讨论 此方法非常适合将data://url转换为NSData对象,也可用于同步读取短文件。如果需要读取可能较大的文件,请使用inputStreamWithURL:打开一个流,然后一次读取一个文件 如果我的理解有误,请随时纠正。如果我认为解决方案能更好地回答我的疑问,我很乐意将我接受的答案改为你的答案