这可能只是一个简单的解决方法,但我对此并不熟悉。
NSString *barImageURLString = barDic[@"image_url"];
NSURL *barImageURL = [NSURL URLWithString:barImageURLString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:barImageURL];
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
cell.barImageView.image = [UIImage imageWithData:imageData];
});
});
NSString *ratingImageURLString = barDic[@"rating_img_url"];
NSURL *ratingImageURL = [NSURL URLWithString:ratingImageURLString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:ratingImageURL];
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
cell.ratingImage.image = [UIImage imageWithData:imageData];
});
});
我不确定如何在那里使用dispatch_async。
答案 0 :(得分:0)
执行POST而不仅仅是代码的重构,它将GET操作隐藏在dataWithContentsOfURL:
中。这是更一般的POST代码...
NSData *data = // init this to the data that you want to post
NSString *someURLString = @"http://www.myservice.com/mypost.php";
NSURL = *url = [NSURL URLWithString:someURLString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
// depends on the data, but something like this to set a header...
[request setValue:@"application/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
request.HTTPBody = data;
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
}
}];
这可以通过用不可变请求替换可变url请求并可选地将查询参数添加到url字符串来重构为GET。
答案 1 :(得分:0)
您的代码在理想条件下工作,但您希望进行一些错误检查以防止运行时异常。
NSString *barImageURLString = barDic[@"image_url"];
NSURL *barImageURL = [NSURL URLWithString:barImageURLString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:barImageURL];
// check for valid data
if ( imageData ) {
// create the UIImage first and make sure it is a valid image
UIImage *image = [UIImage imageWithData:imageData];
if ( image ) {
dispatch_async(dispatch_get_main_queue(), ^{
// It is possible that your tableview cell is no longer on screen, check
YourTableViewCell *cellBeingUpdated = (id)[tableView cellForRowAtIndexPath:indexPath];
if ( cellBeingUpdated ) {
// Update the UI
cellBeingUpdated.barImageView.image = image;
}
});
}
}
});
同样适用于您的其他图片。如果失败,您希望拥有某种默认图像。我做的是有一个默认图像,我在发出图像请求之前分配给tableview单元格。这可以防止在等待实际图像加载时出现空白图像视图。
答案 2 :(得分:0)
由于获取图像并使用它执行某些操作的逻辑大致相同,并且您不希望每次需要加载新类型的图像时重复代码,您可以创建一个函数或方法来执行重复的工作。函数的输入将是图像的URL,输出将是图像本身。由于实际的提取将是异步的,因此该功能可以作为输入一个代码块,其中包含一旦图像可用时应该做什么的指令。如果由于某种原因无法获取图像,也可以通知该块。
- (void)fetchImageFromURL:(NSURL *)imageURL completionHandler:(void(^)(UIImage *image, NSError *error))completionHandler {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
NSError *error = ...; // do error handling if image load fails
dispatch_async(dispatch_get_main_queue(), completionHandler(imageData, error);
});
}
可以调用:
NSString *barImageURL = [NSURL URLWithString:barDic[@"image_url"]];
[self fetchImageFromURL:barImageURL completionHandler:^(UIImage *image, NSError *error) {
if (error != nil) {
// handle error
}
else {
cell.barImageView.image = image;
}
}];
虽然它似乎只是减少了几行重复代码,但这种设计使您的代码更加灵活和可扩展。这隐藏了实际获取图像的实现细节。也许你想用异步NSURLConnection或NSURLSession替换它。此设计允许进行此类修改而不会影响API。错误处理可以保存在一个地方。网络请求可能由于各种原因而失败,其中最重要的原因是糟糕或没有连接。您可以在-fetchImageFromURL:
方法中再次为此类故障添加重试逻辑,而不会影响方法API和调用方。也许你已经建立了一些缓存,所以根本不需要去网络。同样,这种设计可以实现这种增长。
一般而言,您希望将“what”与“how”分开。 what
这里是您的代码的某些部分需要的图像,但它不应该与how
关联的图像被检索。