2011-09-09 34 views
1

我有一个图像缓存类,它将配置文件图像存储在NSMutableDictionary中。如果密钥存在,则缓存返回UIImage对象,如果不存在,则下载它,将其存储在字典中,并返回UIImage。这种共享缓存被称为NSThreaded方法中是这样的:UITableViewCell线程中的图像缓存

[NSThread detachNewThreadSelector:@selector(setImageForUser:) toTarget:self withObject:imageUrlString]; 

-(void)setImageForUser:(NSString *)imageUrlString { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    LPImageCacher *imageCache = [LPImageCacher sharedCache]; 
    UIImage *profileImg = [imageCache getCachedImageFromMemory:imageUrlString]; 
    self.userProfileImageView.image = profileImg; 
    if (profileImg == nil) { 
     imageUrlString = [[myGlobals sharedInstance].avatarUrlDefault stringByAppendingString:@"/avatar.png"]; 
     self.userProfileImageView.image = [imageCache getCachedImageFromMemory:imageUrlString]; 
    } 

    [pool release]; 
} 

的问题是,如果他们滚动的UITableView加载任何东西之前,图像获得积压,然后最终所有的图像加载它们闪烁或改变在当前的单元格上,直到它到达正确的单元格。我认为在每个单元格中创建一个NSThread实例并且仅仅取消-prepareForReuse中的线程会很好,但我似乎无法再次重用NSThread对象,关于如何解决这个问题的任何想法?

回答

0

里德奥尔森给了你直接的答案。我想提到另一件事。

为每个单元调度线程相当昂贵,为什么不使用NSOperationQueue?您可以拥有一组工作线程来完成每个单独的加载,并且将该队列的功能限制在任何时候最大可见单元的数量是有意义的。这几乎是“重用线程”。

事实上,我会建议使用ASIHTTP的ASINetworkQueue。它比NSOperationQueue更简单。

此外,尝试添加一个简单的优化来加载单元格,一旦滚动速度低于某个数字。为什么打扰加载图像,当你无法停下来看到他们?举例来说,我写的是这样的一个的tableView:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    static float prevOffset = 0.0; 
    static float scrollSpeed = 0.0; 

    // positive -> downwards 
    scrollSpeed = scrollView.contentOffset.y - prevOffset; 

    if (scrollSpeed < 2.0) 
    { 
     [self loadImagesForVisibleCellsInTableView:(UITableView*)scrollView]; 
    } 
    else if (scrollSpeed < 6.0) 
    { 
     shouldLoadImages = YES; 
    } 
    else 
    { 
     shouldLoadImages = NO; 
    } 

    prevOffset = scrollView.contentOffset.y; 
} 

这忽略加载新的图像时的tableView快速移动(shouldLoadImages影响tableView:cellForRowAtIndexPath,告诉他们忽略装载图像)时,它的即将停止,它强制重新加载可见单元格。