Do you really know how to reuse UITableViewCell ?, Uitableviewcell Reuse

Source: Internet
Author: User

Do you really know how to reuse UITableViewCell ?, Uitableviewcell Reuse

I. First, let's take a look at the definition of UITableViewCell reuse.

- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;  - (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);

When tableview is created, a reuse pool is created ). this multiplexing pool may be a queue or a linked list that stores the current Cell. the reuse identifier of objects in the pool is reuseIdentifier, which identifies different types of cells. therefore, call dequeueReusableCellWithIdentifier to obtain the cell. the cells obtained from the pool are prototype displayed in tableview. no matter what the status is, set it all.

When UITableView is created, an empty reuse pool is created. then UITableView maintains the reuse pool internally. generally, there are two usage methods: one is to create a new cell when an empty cell is retrieved. one is to pre-register the cell. it is then directly retrieved from the reuse pool without initialization.

Method 1:

- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;  

UITableview: Execute tableView: cellForRowAtIndexPath :. the current reuse pool is empty. call dequeueReusableCellWithIdentifier to retrieve the cell and check whether the cell exists. no cell exists at present, so a new cell is created, Initialization is executed, and return cell.

The Code is as follows:

#define kInputCellReuseIdentifierPWD   @"password_cell"UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kInputCellReuseIdentifierPWD];if (!cell) {    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kInputCellReuseIdentifierPWD];}cell.textLabel.text = @"It is awesome";return cell;

In the code above, the cell you returned will be added to the reuse pool by UITableView. the second call to tableView: cellForRowAtIndexPath: indicates that there is a cell in the reuse pool. at this time, because UITableView is not filled up yet, and the unique one in the reuse pool is already in use. so the Cell is still nil. then, create a new cell and return it. Then add another cell to the reuse pool. The number of cells in the current reuse pool is 2. assume that the current tableview can contain only five cells. when you scroll to 6th cells, the cell obtained from the reuse pool of tableview will be the cell of the first row. similarly, when the number of rows is scrolled to 7th, the cell of the second row will be retrieved from the reuse pool. in addition, we will not continue to use the pool to add new cells.

Method 2:

- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);

Register a UITableViewCell class during UITableView initialization. You do not need to make a short decision;

[tableView registerClass:[BLSProjectMoneyCompleteCell class] forCellWithReuseIdentifier:NSStringFromClass([BLSProjectMoneyCompleteCell class])];

After this method is used, you do not need to judge whether the obtained cell is null, because the obtained cell must exist. call dequeueReusableCellWithIdentifier: when calling the dequeueReusableCellWithIdentifier method, the system first checks whether there is a reusable cell in the current multiplexing pool. if no, tableview will help us create a cell internally. The others are the same as method 1.

BLSProjectMoneyCompleteCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([BLSProjectMoneyCompleteCell class])];

Ii. Problems Caused by UITableViewCell re-use

There can be many cells in UITableView. Generally, cell can be reused to save memory. by specifying a reuseIdentifier for each cell, you can specify the cell type, when the cell is out of the screen, it will put the cell out of the screen into the reused queue. When a cell not on the screen is to be displayed, the cell is retrieved from the queue for reuse.

However, for a variable custom cell, this reuse mechanism sometimes fails. For example, when a cell contains a subclass of UITextField and is placed in the reused queue for reuse, if a cell without any sub-view is displayed on the screen, the reused cell is retrieved and displayed in the cell without any sub-view. In this case, an error occurs.

Method 1:-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath {static NSString * CellIdentifier = @ "Cell "; // UITableViewCell * cell = [tableView failed: CellIdentifier]; // change to the following method: UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath]; // retrieve a row accurately based on indexPath, instead of retrieving if (cell = nil) {cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier] from the cell reuse queue;} //... other code}

Change the method for obtaining the cell from-(UITableViewCell *) handler :( NSString *) identifier to-(UITableViewCell *) cellForRowAtIndexPath :( NSIndexPath *) indexPath. The reuse mechanism calls the handler method, the method means "cell with reusable columns". Therefore, you only need to replace it with cellForRowAtIndexPath (retrieve the cell from the row of the cell to be updated), instead of using the reuse mechanism, therefore, the problem can be solved, although it may waste some space.

Method 2:-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath {NSString * CellIdentifier = [NSString stringWithFormat: @ "Cell % d ", [indexPath section], [indexPath row]; // use indexPath to uniquely determine cell UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // cell if (cell = nil) {cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];} //... other code}

You can solve this problem by specifying different reuseIdentifier for each cell. The reuse mechanism is to reuse cells based on the same identifiers. Cells with different identifiers cannot reuse each other. Therefore, we can set the identifiers of each cell to be different to avoid reuse of different cells.

Method 3:-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath {static NSString * CellIdentifier = @ "Cell"; UITableViewCell * cell = [tableView progress: cellIdentifier]; // reusable cell if (cell = nil) {cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];} else {// delete all child views of a cell While ([cell. contentView. subviews lastObject]! = Nil) {[(UIView *) [cell. contentView. subviews lastObject] removeFromSuperview] ;}//... other code}

Delete all child views of the reused cell. This method deletes all child views of the reused cell to obtain a cell without special format for reuse by other cells. Considering the memory issue, you can add identifiers to each cell when there are few cells. When there are many cells reused, consider the memory issue, we recommend that you delete all the sub-views of a cell (when playing a video ).

Iii. Assertion failure in dequeueReusableCellWithIdentifier: forIndexPath: Crash

In the previous group list, the two groups of cells have different styles. The two groups respectively use the following code (or register the Cell during initialization) and will flash back below IOS9.

static NSString *CellIdentifier = @"Cell";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier                                      forIndexPath:indexPath];

Modified:

static NSString *CellIdentifier = @"Cell";    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];   if (cell==nil) {      cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];    }

 

Related Article

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.