gpt4 book ai didi

ios - NSURL 实现的 UITableView 上的 GCD

转载 作者:行者123 更新时间:2023-11-28 20:15:05 25 4
gpt4 key购买 nike

我一直在尝试在我的项目上实现一个 GCD,它显示从 XML 中获取数据,尽管这是我第一次这样做我已经成功(可能)在 nameLabel 和 detailLabel 上实现,它们都是字符串,但是当我尝试实现与两个字符串相同的 GCD 时,imageLabel(代码的注释部分)没有提供任何信息,我不知道发生了什么,但是当我运行该项目时,它给出了一个未知的异常,我想知道如何在代码的注释部分实现 GCD,这样我就可以在 imageView 中显示图像。

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


static NSString *CellIdentifier = @"CustomCell";

dataFileHolder *currentData = [[xmlParser listPopulated] objectAtIndex:indexPath.row];
CustomCellXMLClass *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];



if(cell == nil) {
cell = [[CustomCellXMLClass alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCellXMLSample" owner:self options:nil];
cell = [nib objectAtIndex:0];

}

myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(myQueue, ^{
NSString *nameLabel = [currentData nameOfCat];
NSString *dataToCacheLabel = [myCache objectForKey:nameLabel];
if(nameLabel != nil){
dataToCacheLabel = [NSString stringWithString:nameLabel];
if (dataToCacheLabel != nil) {
[myCache setObject:dataToCacheLabel forKey:nameLabel];
dispatch_async(dispatch_get_main_queue(), ^{
[cell.nameLabel setText:dataToCacheLabel];
});
}
}



NSString *detailLabel = [currentData descriptionOfCat];
NSString *stringToCache = [myCache objectForKey:detailLabel];
if (detailLabel != nil) {
stringToCache = [NSString stringWithString:detailLabel];
if (stringToCache != nil) {
[myCache setObject:stringToCache forKey:detailLabel];
dispatch_async(dispatch_get_main_queue(), ^{

[cell.detailLabel setText:stringToCache];
});
}
}

// NSString *imageURL = [currentData imageLink];
// NSData *dataToCache;
// if (imageURL != nil) {
//
// dataToCache = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
// if (dataToCache != nil) {
//
// [myCache setObject:dataToCache forKey:imageURL];
// [cell.imageShow setImage:[UIImage imageWithData:dataToCache]];
//
// }
// else {
//
// NSURL *imageURL = [NSURL URLWithString:@"http://i178.photobucket.com/albums/w255/ace003_album/190579604m.jpg"];
// dataToCache = [NSData dataWithContentsOfURL:imageURL];
// [myCache setObject:dataToCache forKey:imageURL];
// [cell.imageShow setImage:[UIImage imageWithData:dataToCache]];
// }
//
// }
[self.activityIndicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES];

});
return cell;

}

最佳答案

您需要将更新单元格的部分分派(dispatch)回主线程,就像您对前两个部分所做的那样。这部分:dispatch_async(dispatch_get_main_queue(),...) 它可能看起来像这样:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CustomCell";
static NSInteger usageCount = 0;

dataFileHolder *currentData = [[xmlParser listPopulated] objectAtIndex:indexPath.row];
CustomCellXMLClass *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if(cell == nil) {
cell = [[CustomCellXMLClass alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCellXMLSample" owner:self options:nil];
cell = [nib objectAtIndex:0];
}

// Give it a new tag every time, so we can tell if this is "our" use of the cell
cell.tag = ++usageCount;

myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(myQueue, ^{
NSString *nameLabel = [currentData nameOfCat];
NSString *dataToCacheLabel = [myCache objectForKey:nameLabel];
if(nameLabel != nil){
dataToCacheLabel = [NSString stringWithString:nameLabel];
if (dataToCacheLabel != nil) {
[myCache setObject:dataToCacheLabel forKey:nameLabel];
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.superview && usageCount == cell.tag)
{
[cell.nameLabel setText:dataToCacheLabel];
}
});
}
}

NSString *detailLabel = [currentData descriptionOfCat];
NSString *stringToCache = [myCache objectForKey:detailLabel];
if (detailLabel != nil) {
stringToCache = [NSString stringWithString:detailLabel];
if (stringToCache != nil) {
[myCache setObject:stringToCache forKey:detailLabel];
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.superview && usageCount == cell.tag)
{
[cell.detailLabel setText:stringToCache];
}
});
}
}

NSURL *fallbackImageURL = [NSURL URLWithString:@"http://i178.photobucket.com/albums/w255/ace003_album/190579604m.jpg"];
NSString *imageURL = [currentData imageLink];
NSArray* urls = imageURL ? @[ imageURL, fallbackImageURL ] : @[ fallbackImageURL ];
for (NSURL* url in urls)
{
UIImage* cachedImage = [myCache objectForKey: url];
if (!cachedImage)
{
NSData* imageData = [NSData dataWithContentsOfURL:url];
cachedImage = [UIImage imageWithData:dataToCache];
[myCache setObject:cachedImage forKey:url];
}

if (cachedImage)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.superview && usageCount == cell.tag)
{
[cell.imageShow setImage: uiImage];
}
});
break;
}
}
});
return cell;
}

从长远来看,您可能还应该考虑使用多种异步加载方法中的任何一种来代替 dataWithContentsOfURL:,后者会阻塞后台线程等待数据被完全接收。但这是次要问题,而不是你问的问题。

编辑: 针对@Rob 的评论进行了编辑。在获取之前检查缓存中是否有预缓存的图像,并防止将值写入重用或不可见的单元格(假设您没有将 tag 用于其他用途。)但实际上,只需使用异步图像下载管理器。

关于ios - NSURL 实现的 UITableView 上的 GCD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18363501/

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