IOS cell asynchronous picture loading optimization, caching mechanism explained

Source: Internet
Author: User

Recently, the problem of asynchronously loading network images in Uitbleview has been studied, and iOS apps often see this interface.
A tableview shows some titles, details, and so on, plus a picture.
Let's talk about this idea here.

To prevent images from being downloaded multiple times, we need to cache the images and cache them in the sandbox cache, both of which we have to implement.
Since Tableviewcell is a reusable mechanism, that is, only an instance of the currently visible number of cells in memory, when sliding, a new display cell reuses the cell object that is being slid out. So there is a problem:

In general, in the Cellforrow method we will set the cell image data source, that is, if a cell ImageView object opens a download task, this time the cell object has been reused, the new image data source will open another download task , 2 download task callbacks to the same ImageView object occur because their associated ImageView object is actually the ImageView object of the same cell instance. At this point it is necessary to do some processing to avoid the wrong image data source refreshing the UI when the callback occurs.

So when we slide down the tableview we need to manually cancel the drop-down operation, when the user stops swiping and then goes to the download operation. This strategy is also used by Sdwebimage.

Very simple we only need to listen to the ScrollView proxy method (TableView inherits from ScrollView).

/** *  当用户开始拖拽表格时调用 */- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{    // 暂停下载    [self.queue setSuspended:YES];}/** *  当用户停止拖拽表格时调用 */- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{    // 恢复下载    [self.queue setSuspended:NO];}

and sdwebimage only use this way, so in the run Sdwebimage of the demo, you can see, if the fast slide down, and then slide back, the picture is a moment before the show, this is because the fast sliding, the old data source download task was canceled.
/-------------------------------------------

Here's a look at the specific ideas.
Download images asynchronously we use nsoperation and create a global queue to manage the operation of downloading pictures.

/** *  存放所有下载操作的队列 */@property (nonatomic,strong) NSOperationQueue* queue;

Also need two dictionaries operations, images

/** *  存放所有的下载操作(url是key,operation对象是value) */@property (nonatomic,strong) NSMutableDictionary* operations;/** *  存放所有下载完成的图片,用于内存缓存,同样用Url为key */@property (nonatomic,strong) NSMutableDictionary* images;

Before displaying the picture on the cell
First determine if there is a picture in memory (in the images dictionary),
If so, then take out the URL corresponding to the picture to display,
If not, then go to the sandbox cache to see, of course, stored in the sandbox is nsdata.
If there is a sandbox cache, we remove the corresponding data to the cell to display
If there is no picture in the sandbox, we first display the placeholder picture. Create operation again to perform the download operation.
Of course, before we create the operation, we need to determine if the operation operation exists.
This is the time for us to operations this dictionary.

//取出当前URL对应的下载操作NSBlockOperation* operation = self.operations[app.icon];

If there is no download operation, we need to actually create operation to perform the download.
After the download operation is created, it should be stored in the global queue to execute asynchronously, while the operation is recorded in the Operations dictionary.

//添加操作到队列中  [self.queue addOperation:operation];//添加到字典中   self.operations[app.icon] = operation;

After the download is complete:
Put downloaded images into memory and store them in the sandbox cache
The code stored in the sandbox below can be defined by macro, which can be downloaded from the following demo

if (image) { //防止下载失败为空赋值造成崩溃  vc.images[app.icon] = image;  //下载完成的图片存入沙盒中                      // UIImage --> NSData --> File(文件)     NSData* ImageData = UIImagePNGRepresentation(image);     NSString* CachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];     NSString* filePath = [CachesPath stringByAppendingPathComponent:[app.icon lastPathComponent]];     [ImageData writeToFile:filePath atomically:YES];           }

After performing the above operation, go back to the main thread refresh table,
Remove the download from the Operations dictionary (to prevent operations from getting bigger, and to re-download after the download fails)

//刷新当前行的图片数据  self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

Here we do not need [Self.tableview reloadata], because the entire cell will be refreshed, wasting performance.

Of course if you need to do a lot of things in the download operation, you can consider customizing the operation. Since I am just a simple download of the small map there is no custom operation. Note To create an auto-free pool yourself.

IOS cell asynchronous picture loading optimization, caching mechanism explained

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.