2012-01-31 48 views
2

第一次加載遠程圖像轉換爲iPhone應用程序,並希望一些幫助優化工藝。我目前做的是獲取圖像,如果它不存在,並緩存它。主要目標是:目標C自定義延遲加載圖片的UITableView細胞

  • 只在需要時加載圖像。
  • 保存圖像以供將來使用,以減少數據量,並允許用戶有幾分功能的應用程序時未連接到互聯網。

我只是覺得我做得不夠好。

這裏的代碼片段內的tableView:的cellForRowAtIndexPath:

MVImageCell * cell = (MVImageCell *)[tableView dequeueReusableCellWithIdentifier:@"PicsAndVideosCell"]; 

// empty cell 
cell.imageView.image = nil; 
cell.textLabel.text = nil; 
cell.detailTextLabel.text = nil; 

// set cell properties 
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap; 
cell.textLabel.numberOfLines = 2; 
cell.imageView.contentMode = UIViewContentModeScaleAspectFit; 
cell.imageView.frame = CGRectMake(15, 6, 58, 58); 
cell.imageView.layer.cornerRadius = 6; 
cell.imageView.layer.masksToBounds = YES; 

Photoset * sfc = [self.myarray objectAtIndex:indexPath.row]; 
cell.cid = sfc.sfcid; 
cell.ctitle = sfc.title; 
cell.cimg = sfc.cover; 

cell.textLabel.text = sfc.title; 
cell.detailTextLabel.text = sfc.date; 

// set cell image 
MVImage * thumb = [[MVImage alloc] init]; 
NSString * retina = ([[MVProject sharedInstance] settings_retina]) ? @"2" : @""; 
if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]]) { 
    thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]]; 

    [cell.imageView setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f]]; 
    [cell bringSubviewToFront:[cell.imageView superview]]; 
} else { 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      thumb.data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", cell.cimg]]]; 
      thumb.title = cell.ctitle; 
      [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:thumb] forKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]; 

      [cell.imageView setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f]]; 
      [cell bringSubviewToFront:[cell.imageView superview]]; 
     }); 
    }); 
} 

return cell; 

我應該使用SQLite數據庫的NSUserDefaults的不是?

我還分別具有與異步加載的麻煩。我覺得它應該看起來像這樣:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
dispatch_async(queue, ^{ 
    thumb.data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", cell.cimg]]]; 
    thumb.title = cell.ctitle; 
    [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:thumb] forKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]; 

    dispatch_sync(dispatch_get_main_queue(), ^{ 
     [cell.imageView setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f]]; 
     [cell bringSubviewToFront:[cell.imageView superview]]; 
    }); 
}); 

但是,這顯然將錯誤的圖像數據保存到NSUserDefault目標。

對此的任何幫助,我的編碼風格的指針和其他任何東西都非常感謝。

謝謝!

回答

5

只需快速查看代碼 - 您似乎將塊推入異步隊列中,但您在這些塊中調用UI代碼。

您應該只在主線程上運行的UI代碼。

至於一個解決方案 - 看看一些開源實現,或者讓你知道你應該做什麼,或者直接使用它們。

其中之一就是Github上的AsyncImageView

另外有一些人快速搜索將彈出。

2

2意見建議: 1.不要在NSUserDefaults中存儲圖像,這是更適合用戶喜好,如字符串。

  1. 不要做兩次解除存檔操作。只要做到這一點,然後檢查結果。

替換此:

if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]]) { 
thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]]; 

利用該:

thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]]; 
if (thumb) ... 
+0

將 '如果(拇指= [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults的standardUserDefaults] objectForKey:[的NSString stringWithFormat:@「Settings_SFCCovers %@ _%@「,retina,cell.cid]]]){...}' return true? – 2012-01-31 17:03:37

+1

如果取消存檔操作成功,那麼可以,該表單同樣適用。 – Rayfleck 2012-01-31 17:07:02

+0

不幸的是,這些解決方案都不正確。他們總是回報錯誤。 – 2012-01-31 17:15:31