gpt4 book ai didi

ios - 如何在 Objective-C 中使用 NSURLSession 从服务器下载 100 张图像

转载 作者:行者123 更新时间:2023-11-28 23:57:16 26 4
gpt4 key购买 nike

我正在制作一个应用..

我需要从服务器下载很多图片,但我不知道该怎么做

之前我是通过阅读一些文章来做到这一点的

目前面临一些问题 滚动时图像会一直闪烁并变化。当快速向后滚动时,所有图像都是错误的。我该怎么办?

- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, UIImage *image))completionBlock
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
UIImage *image = [[UIImage alloc] initWithData:data];
completionBlock(YES,image);
} else{
completionBlock(NO,nil);
}
}];
}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"venue";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}

Venue *venue = ((Venue * )self.venues[indexPath.row]);
if (venue.userImage) {
cell.imageView.image = venue.image;
} else {
// set default user image while image is being downloaded
cell.imageView.image = [UIImage imageNamed:@"default.png"];

// download the image asynchronously
[self downloadImageWithURL:venue.url completionBlock:^(BOOL succeeded, UIImage *image) {
if (succeeded) {
// change the image in the cell
cell.imageView.image = image;

// cache the image for use later (when scrolling up)
venue.image = image;
}
}];
}
}

**任何最好的方法建议**

最佳答案

我在您的代码中发现了一些问题,所以让我首先举一个您需要的最低限度的示例:

- (void)downloadImageFrom:(NSURL *)path completion:(void (^)(UIImage *image))completionBlock {
dispatch_queue_t queue = dispatch_queue_create("Image Download", 0);
dispatch_async(queue, ^{
NSData *data = [[NSData alloc] initWithContentsOfURL:path];
dispatch_async(dispatch_get_main_queue(), ^{
if(data) {
completionBlock([[UIImage alloc] initWithData:data]);
} else {
completionBlock(nil);
}
});
});
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

MyTableViewCell *cell = ...; // Create my own cell
NSString *imageURL = ...; // Get from my model

cell.imageURLString = imageURL;
[self downloadImageFrom:[NSURL URLWithString:imageURL] completion:^(UIImage *image) {
if(cell.imageURLString == imageURL) {
cell.imageView.image = image;
}
}];
return cell;
}

首先,下载时(无论您使用什么)确保您在正确的线程上。我使用了最简单的工具来下载使用 NSData 的远程图像,只要您的请求不需要额外的数据(如凭据),它就可以很好地工作。您没有理由更改它,但请确保您在主线程上调用完成。

接下来您遇到的是多线程加上单元格出队的问题。在 TableView 中,将重复使用相同的单元格。当您向下滚动时,一个向上移动离开屏幕的单元格将出现在底部。这是为了获得性能。

现在,因为您向上和向下滚动并且图像异步加载,完成 block if (succeeded) { 可能会被调用,因为它似乎是一个不正确的单元格。您需要做的是检查调用是否仍然有效。

因此您应该将您的单元格子类化并至少添加一些标识符,例如 imageURLString。您在调用以获取图像之前设置它,然后在完成时再次检查单元格标识符是否仍然相同。如果不是,则您的手机已被重复使用,下载的图像将被丢弃。

这也意味着您应该创建某种图像缓存。这样,丢弃的图像并没有真正被丢弃,而是被缓存起来,如果出现相同的单元格,则不会再次下载。

关于ios - 如何在 Objective-C 中使用 NSURLSession 从服务器下载 100 张图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50848392/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com