2016-05-13 165 views
1

滚动时冻结我有这个问题,约3-4周。我GOOGLE了一下,检查了一切,但仍然没有工作。请帮帮我!的UITableView在迅速

在每一个移动滚动cellForRowAtIndexPath重载tableView所以,它开始冻结。

我为cellForRowAtIndexPath功能的tableview是这样的:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 

    let cell = tableView.dequeueReusableCellWithIdentifier("cell")! as! MoviesTVC 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),{ 
     let dictionary = self.rows[indexPath.row] as? [String: AnyObject] 
     dispatch_async(dispatch_get_main_queue(),{ 
      cell.setCell(dictionary!) 
     }) 

    }) 

    return cell 
} 

setCell()功能:

func setCell(dictionary: AnyObject){ 
    let ImgString = dictionary["src"] as? String; 
    let ImgUrl = NSURL(string: ImgString!); 
    let ImgData = NSData(contentsOfURL: ImgUrl!) 
    self.movImg.image = UIImage(data: ImgData!); 
    self.movName.text = dictionary["name"] as? String; 
    self.movComment.text = dictionary["caption"] as? String; 
} 
+0

除了Putz1103的观察之下,更新小区的这个过程异步比你的代码变得更加复杂(或他)的设想。您应该考虑(a)在异步请求完成时重新使用单元; (b)快速滚动,其中可见的单元格图像请求滞留在已经滚出视图的单元的未决请求之后;等等。要做好这一切并不难,您可以考虑一个'UIImage'扩展,它更加优雅地处理异步图像检索。请参阅http://stackoverflow.com/a/33505649/1271826。 – Rob

+0

您应该检查单元在async调用后是否仍然对应给定的索引路径(也许它是在屏幕外滚动的)。另外,请避免使用!运营商,也许你应该使用“如果让” –

回答

2

你的代码错了位在后台异步任务。目前,您只得到从阵列的背景下,这是一个非常非常快的过程......

你应该做的是在后台运行的艰巨任务,然后更新在前台UI的值。

let cell = tableView.dequeueReusableCellWithIdentifier("cell")! as! MoviesTVC 
let dictionary = self.rows[indexPath.row] as? [String: AnyObject] 
cell.setCell(dictionary!) 

return cell 


func setCell(dictionary: AnyObject){ 
    let ImgString = dictionary["src"] as? String; 
    let ImgUrl = NSURL(string: ImgString!); 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),{ 
     let ImgData = NSData(contentsOfURL: ImgUrl!) 
     let image = UIImage(data: ImgData!); 
     //Possibly resize the image here in the background task 
     //so that the cpu doesn't need to scale it in the UI thread 
     dispatch_async(dispatch_get_main_queue(),{ 
      self.movImg.image = image 
     }) 
    }) 
    self.movName.text = dictionary["name"] as? String; 
    self.movComment.text = dictionary["caption"] as? String; 
} 

编辑:在评论中回答你的问题。最简单的解决方案是为每个“图像”单元添加一个属性到字典中。然后,如果字典的“图像”属性存在,则在加载单元格时,您可以将该图像加载到单元格中。如果不存在,请下载并保存到字典中,然后将其添加到您的单元格中。

较硬的解决方案,这将是图像下载到本地资源位置。然后使用imageNamed从文件加载图像。这将为您处理缓存和内存释放。这将是更好的选择。

更妙的是使用CoreData。在这些解决方案中的任何一个中,您在运行时都必须管理清除文件存储。

+0

谢谢!冻结问题解决了,但在这种情况下图像下载每个移动滚动。我的意思是,在滚动期间调用setCell()函数。你有什么建议吗? –

+0

@CeyhunAshurbeyli看我的编辑。 – Putz1103

+0

@CeyhunAshurbeyli - 您一般会在滚动时想要启动图像请求(例如,向下滚动以显示另外三行,因此您希望立即请求这些图像)。诀窍是你想停止对已经滚屏的单元格的请求,但还没有完成下载图像。这意味着不使用'NSData(contentsOfURL:)'。有很多很好的'UIImageView'扩展可以很好地处理这些东西,并让你摆脱杂草。 – Rob