2012-02-08 29 views
5

我需要從網頁/文件加載一些UIImages。我在尋找,我在其他question發現這個代碼:UITableViewCell加載圖像和重用單元格

if (![[NSFileManager defaultManager] fileExistsAtPath:user.image]) { 
     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
     dispatch_async(queue, ^{ 
      NSData *imageData =[NSData dataWithContentsOfURL:[NSURL URLWithString:user.imageURL]]; 

      [imageData writeToFile:user.image atomically:YES]; 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
       UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
       UIImage *image = [UIImage imageWithData:imageData]; 
       [self.imageFriends setObject:image forKey:[NSNumber numberWithInt:user.userId]]; 
       cell.imageView.image = image; 
       [cell setNeedsLayout]; 
       NSLog(@"Download %@",user.image); 
      }); 
     }); 
     cell.imageView.image=[UIImage imageNamed:@"xger86x.jpg"]; 
    } else { 
     NSLog(@"cache"); 
     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
     dispatch_async(queue, ^{ 
      UIImage *image = [UIImage imageWithContentsOfFile:user.image]; 
      //[self.imageFriends setObject:image forKey:[NSNumber numberWithInt:user.userId]]; 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
       UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath]; 
       newCell.imageView.image=image; 
       [newCell setNeedsLayout]; 
      }); 
     }); 
    } 

但問題是,當我快速滾動到頂部或底部的圖像加載錯誤,有一個短暫的延遲何時結束。

所以問題是......我如何在正確的單元格中加載UIImages,當我使用隊列來獲取它們時?謝謝!

回答

7

我懷疑你看到的圖片不正確的是你,不是在你的事件設置你的地方持有人圖像具有圖像的本地副本,但仍檢索本地結果異步複製。另外在附加的用於加載本地副本的代碼中,您在後臺線程上使用UIImage a UIKit組件。

也有趣的是,你似乎在做某種UIImage緩存。將圖像添加到我認爲的NSMutableArray屬性imageFriends。但是,如果您擁有文件的本地副本,您似乎已經註釋了緩存添加。您的發佈代碼也不會使用緩存的UIImages

雖然2級高速緩存的似乎有點過分,如果你想做到這一點,你可以做這樣的事情:

UIImage *userImage = [self.imageFriends objectForKey:[NSNumber numberWithInt:user.userId]]; 
if (userImage) { // if the dictionary of images has it just display it 
    cell.imageView.image = userImage; 
} 
else { 
    cell.imageView.image = [UIImage imageNamed:@"xger86x.jpg"]; // set placeholder image 
    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:user.image]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     NSData *imageData = nil; 
     if (fileExists){ 
      imageData = [NSData dataWithContentsOfFile:user.image]; 
     } 
     else { 
      imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:user.imageURL]]; 
      [imageData writeToFile:user.image atomically:YES]; 
     } 
     if (imageData){ 
      dispatch_async(dispatch_get_main_queue(), ^{ 
        // UIKit, which includes UIImage warns about not being thread safe 
        // So we switch to main thread to instantiate image 
       UIImage *image = [UIImage imageWithData:imageData]; 
       [self.imageFriends setObject:image forKey:[NSNumber numberWithInt:user.userId]]; 
       UITableViewCell *lookedUpCell = [tableView cellForRowAtIndexPath:indexPath]; 
       if (lookedUpCell){ 
        lookedUpCell.imageView.image = image; 
        [lookedUpCell setNeedsLayout]; 
       } 
      }); 
     } 
    }); 
} 

UIImage s爲的UIKit一部分,而不是線程安全的。但是你可以在另一個線程上加載NSData

+0

關於UIImage不是線程安全的說明是我試圖解決的問題的關鍵。 – JamesSwift 2013-12-10 03:04:10

6

您正在異步加載圖像,因此在快速滾動過程中,重複使用單元格會更快,然後下載圖像。避免加載錯誤圖像的一種方法是檢查圖像加載時單元是否已被重用。或者在您退出新單元格時取消正在進行的所有請求。

我也建議看AFNetworking,因爲它包含有用的類別UIImageView,所以你可以做這樣的事情:

[imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]]; 

它還包含cancelImageRequestOperation方法,來取消正在進行的請求。然後,你的代碼看起來就像這樣:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
} else { 
    [cell.imageView cancelImageRequestOperation]; 
} 
[cell.imageView setImageWithURL:[NSURL URLWithString:user.imageURL] placeholderImage:[UIImage imageNamed:@"xger86x.jpg"]]; 
相關問題