我有一个段和一个表视图,我必须在表视图中重新加载数据,但当我快速切换段按钮时,应用程序崩溃。
在段上,我有三个按钮,在它们的操作上,我触发了对 url 的请求并从该 url 获取 json(分别为 3 个不同的 url,并在 json 中返回 10、17 和 8 个结果)。
我有一个自定义表格单元格,其中包含图像,我正在尝试延迟加载这些图像。
在 JSON 结果中,每个 json 对象都有不同的键,例如 name、id、imageurl 等。
id 在整个应用程序中是唯一的,我正在尝试加载图像并将图像保存在基于该唯一 id 的本地内存中,这样我就可以显示已兑现的图像,而无需在段更改时重新下载图像,因为有些条目在所有三个部分都是相同的。
这是我的完整代码
- (IBAction)segmentedControlIndexChanged {
NSString *offerRequestUrl = nil;
switch (self.mySegment.selectedSegmentIndex) {
case 0:
offerRequestUrl = @"url_one";
self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl];
break;
case 1:
offerRequestUrl = @"url_two";;
self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl];
break;
case 2:
offerRequestUrl = @"url_three";;
self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl];
break;
default:
break;
}
[self parseJSONWithURL:self.feedRequestUrl];
}
- (void) parseJSONWithURL:(NSURL *) jsonURL
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL: jsonURL];
[self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
self.feedsArray = [json objectForKey:@"result"];
[self.myTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int count = self.feedsArray.count;
// if there's no data yet, return enough rows to fill the screen
if (count == 0)
{
return 1;
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// customize the appearance of table view cells
//
static NSString *CellIdentifier = @"MyTableCell";
static NSString *PlaceholderCellIdentifier = @"PlaceholderCell";
// add a placeholder cell while waiting on table data
int nodeCount = [self.feedsArray count];
if (nodeCount == 0 && indexPath.row == 0)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:PlaceholderCellIdentifier];
cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.detailTextLabel.text = @"Loading . . .";
[self performSelector:@selector(checkAndDisplayAlert) withObject:self afterDelay:10.0];
return cell;
}
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nodeCount > 0)
{
// Configure the cell...
cell.carImageView.image = [UIImage imageNamed:@"Placeholder"]; //acts as default image
if([self.imageDict valueForKey:[NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]]==nil)
{
[NSThread detachNewThreadSelector:@selector(displayingSmallImage:) toTarget:self withObject:indexPath];
} else {
cell.carImageView.image = [self.imageDict valueForKey:[NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]];
}
cell.imageView.clipsToBounds = YES;
cell.titleLabel.text = self.feedsArray[indexPath.row][@"title_key"];
}
return cell;
}
- (void) displayingSmallImage:(NSIndexPath *)indexPath
{
NSString *imageUrl = self.feedsArray[indexPath.row][@"icon_url"];
NSURL *url = [NSURL URLWithString:imageUrl];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
if(image == nil)
{
image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Placeholder"]];
}
[self.imageDict setObject:image forKey:[NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]];
[self performSelectorOnMainThread:@selector(imageReceived:) withObject:indexPath waitUntilDone:NO];
}
- (void) imageReceived:(NSIndexPath *)indexPath
{
UIImage *image = (UIImage *)[self.imageDict objectForKey: [NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]];
UIImageView *imgs = (UIImageView *)[[self.myTableView cellForRowAtIndexPath:indexPath] viewWithTag:IMG_TAG];
[imgs setImage:image];
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
- (void) checkAndDisplayAlert
{
if (!self.feedsArray && self.isAlertPresent == NO) {
UIAlertView *nilAlert = [[UIAlertView alloc] initWithTitle:@"Sorry!"
message:@"No result returned from server."
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[nilAlert setTag:kNilAlertTag];
self.isAlertPresent = YES;
[nilAlert show];
}
}
我要做的主要事情是
懒惰下载图片
根据唯一 ID 将图像缓存在本地内存中
检查已下载图像的兑现图像字典并显示它
如果可能的话,将这些下载的图像保存在本地内存中(nsuserdefaults 等),这样如果用户重新启动应用程序,图像也会在那里并且可以根据其唯一 ID 显示,无需再次下载。
任何帮助,将不胜感激。