AFNetworking下载数千个异步图像会降低app的速度

时间:2014-05-02 13:22:41

标签: ios uiimage afnetworking

我正在通过AFNetworking异步下载数千张图片并将它们存储在iDevice中,但是当我在控制台上显示错误时我的应用程序变慢了#34;响应超时"

以下是我用来下载图片的代码。

[NSThread detachNewThreadSelector:@selector(DownloadImages) toTarget:self withObject:nil];
 -(void)DownloadImages
{
 for(int i = 0; i<=4600;i++)
    {
        NSString *FrameSmall = [NSString stringWithFormat:@"myimageurl%i.png",i];
        [self setbuttonImg:FrameSmall];
    }
}
-(void)setbuttonImg:(NSString *)str    
{
NSArray* badWords = @[@":", @"/", @".",@" "];
NSMutableString* mString = [NSMutableString stringWithString:str];

for (NSString* string in badWords) {
    mString = [[mString stringByReplacingOccurrencesOfString:string withString:@""] mutableCopy];
}

NSString *encoded = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:encoded]];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    [self saveImage:responseObject withFileName:mString ofType:@"png" inDirectory:documentsDirectoryPath];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     }];
[requestOperation start];
}

-(void) saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
if ([[extension lowercaseString] isEqualToString:@"png"]) {
    [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil];
} else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"]) {
    [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil];
} else {
    //  ALog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", extension);
}

}

2 个答案:

答案 0 :(得分:5)

所有图片都是同时下载的,这不是一个好主意。

您可以使用AFHTTPRequestOperationManager上的operationQueue设置最大并发度

http://cocoadocs.org/docsets/AFNetworking/2.0.0/Classes/AFHTTPRequestOperationManager.html#//api/name/operationQueue

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.operationQueue.maxConcurrentOperationCount = 5; //set to max downloads at once.

答案 1 :(得分:3)

最佳做法是仅加载用户将立即看到的图像 - 因此只能查看视图中的图像。通常,这意味着只存储URL,然后在实际需要时加载图像。在UIImageView上只使用自定义类别(AFNetworking提供类似的类别),您可以使用以下方法将图像加载到自定义表格视图单元格中:

- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
              placeholderImage:(UIImage *)placeholderImage
                       success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success
                       failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure;

以下是围绕该类别定制包装的示例:

- (void)tableView:(UITableView *)tableView
  willDisplayCell:(GameTableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
  cell.backgroundColor = [UIColor clearColor];
  id game = [self.games objectAtIndex:indexPath.row];
  if([game isKindOfClass:[Game class]])
  {
    Game *aGame = (Game *)game;
    cell.titleLabel.text = aGame.gameName;
    cell.descriptionLabel.text = aGame.gameDescription;
    cell.playGameButton.layer.cornerRadius = 8.0F;
    [cell.imageView loadImageFromRemoteURL:aGame.imageURL
                       withPlaceholder:[UIImage imageFromAssetsNamed:@"game_icon"]
                     completionHandler:^(UIImage *fetchedImage, NSError *error)
     {
       if(nil == error)
       {
         aGame.image = fetchedImage;
         // Note: Need to set the image in an imageView somewhere on the main thread.
       }
     }];
  }
}

这意味着只有屏幕上的游戏单元才能加载图像而不是一次加载它们。