Using AlamofireImage Inside UITableViewCell

2019-06-16 09:03发布

I've been reading a lot of answers here saying that by using AlamofireImage helper methods (e.g. af_setImageWithURL()) or any equivalent library, you don't need to worry about cell reusing stuff (Plus, many published tutorials actually just do that). That is to say, I don't have to keep a weak reference to the cell or getting it by using tableView's cellForRowAtIndexPath() method to update its imageView after the background downloading finishes, like what we usually do if request made manually.

First of all, is that true? And if so, how it was done inside the library, cause I tried to trace AlamofireImage's af_setImageWithURL() code, and I cannot find any effort made to make sure we're still working on the same cell we made the request from. Am I missing something?

I am sorry if it sounds stupid, but I am really confused.

1条回答
来,给爷笑一个
2楼-- · 2019-06-16 09:48

Assuming you're talking about the UIImageView category, yes, it does solve a number of problems that plague naïve asynchronous image retrieval issues, namely:

  • If a cell is inserted above or below the cell in question, the fact that the NSIndexPath has changed will not affect the asynchronous updating of the image for the cell in question.

  • If you scroll quickly to row 100, as you call af_setImageWithURL on reused cells, the requests for prior rows that were previously associated with this reused cell will be canceled.

    • One implication of this is that it avoids the image view for a visible row getting updated with the image request for the image for the row previously associated with this reused cell. (This avoids the "flickering" of images on slow connections that simplistic implementations can experience.)

    • Another implication of this is that it avoids the performance problem where the image associated for cell 100 could get backlogged behind the image request for rows 1-99.

  • AlamofireImage also provides image resizing routine, which is important when showing thumbnail images for cells. If you don't resize images, you can have extravagant memory usage if using large assets (especially in collection views in which many thumbnail images may be visible).

In terms of UITableViewCell issues that AlamofireImage might not handle as gracefully as we'd like, it includes:

  • Regarding caching, AlamofireImage relies upon the underlying NSURLCache rather than doing its own caching via NSCache or to local persistent storage. While I understand why the author did that (there's a certain intuitive appeal, insofar as NSURLCache should be able to do this elegantly), you should be aware that NSURLCache can be problematic, only cacheing in accordance with poorly documented rules (if resource exceeds 5% of total cache size, it doesn't get cached; it won't cache if the HTTP headers aren't quite right, etc.). So one has to be careful on the caching issue.

  • Regarding preheating (the prefetching of images for cells that are adjacent to the visible rows), AlamofireImage doesn't do much here. You might want to see some low priority request management for cells that are adjacent to the visible rows, so that visible cell performance isn't adversely affected, but also so that the images associated with those rows are already when the user scrolls.

Bottom line, it is an overstatement to say "you don't need to worry about cell reusing stuff" when using a UIImageView category. You still need to carefully design your cell reuse logic, e.g.:

  • Make sure you don't have any paths that bypass the updating of the image view, even if the row in question might not have an image to show;
  • Identify whether image resizing is necessary;
  • Confirm that NSURLCache is caching correctly in your situation;
  • Decide whether you want to create and cache thumbnails;
  • Etc.

But it is true that a well-executed UIImageView category can forestall many pitfalls of overly-simplistic asynchronous image retrieval routines. But it's no silver bullet.

查看更多
登录 后发表回答