Today, when I was looking at the iphone development secret, I encountered this problem. I carefully went into depth and obtained some conclusions that I think are not bad, I hope this will be helpful for some problems encountered in cell reuse.
This article only describes the principle. If you do not elaborate on the cell interface. In view of my limited expression ability, I may be clear about it, but leave a message to me if I have any questions.
UITableView is widely used in Interface Programming, and iphone development is also more than March. Every time you use the cellForRowAtIndexPath delegate method, you directly copy the code and add some interface modifications, the cell identifier is static NSString * identifier = @ "cell"; then call the dequeueReusableCellWithIdentifier method to obtain the cell. If the cell is empty, call the [[[UITableViewCellalloc] initWithStyle method to create a new one, without any further consideration. For the sake of clarity, I now put a piece of code, the code is copied from the iphone development cheats, I want to explain, slightly modify. All of the following are explained in accordance with this Code. Therefore, if you want to thoroughly understand the cell reuse mechanism, we recommend that you run the following. The Code only has the tableVIew delegate method. Therefore, you need to create your own project and add these delegate methods.
The preceding four delegate methods indicate that a section in tableView has 32 rows and the height is 58. for the height of tableView, which is the height value returned by the delegate method, it is recommended that you run the program to view the following. The page displays 8 cells and 8th cells, but it cannot display 9 or 7 cells. Here I am 58, because (480-44)/58 is 7.5, 44 is the height of navigationBar, and 480 is the height of the screen. In short, the result is that more than seven cells are displayed on one page. You need to prepare the icon.png and display it. Is it very troublesome? No way. Who makes us gain knowledge? It always takes some effort to get knowledge.
[Cpp]
-(NSInteger) numberOfSectionsInTableView :( UITableView *) aTableView
{
Return 1;
}
-(NSInteger) tableView :( UITableView *) aTableView numberOfRowsInSection :( NSInteger) section
{
Return 32;
}
-(CGFloat) tableView :( UITableView *) tableView heightForRowAtIndexPath :( NSIndexPath *) indexPath
{
Return 58;
}
-(UITableViewCell *) tableView :( UITableView *) tView cellForRowAtIndexPath :( NSIndexPath *) indexPath
{
UITableViewCellStyle style;
NSString * cellType;
Switch (indexPath. row % 4)
{
Case 0:
Style = UITableViewCellStyleDefault;
CellType = @ "Default Style ";
// There is a title and no body (no detailed text ). Optional Images
Break;
Case 1:
Style = UITableViewCellStyleSubtitle;
CellType = @ "Subtitle Style ";
// The title and body are arranged up and down. Optional Images
Break;
Case 2:
Style = UITableViewCellStyleValue1;
CellType = @ "Value1 Style ";
// Align the left text with the right text. Optional Images
Break;
Case 3:
Style = UITableViewCellStyleValue2;
CellType = @ "Value2 Style ";
// The left text is right aligned and blue; the right text is left aligned and black. No Image
Break;
}
Static int I = 0;
UITableViewCell * cell = [tView dequeueReusableCellWithIdentifier: cellType];
If (! Cell)
{
Cell = [[[UITableViewCell alloc] initWithStyle: style reuseIdentifier: cellType] autorelease];
++ I;
NSLog (@ "cell created % d times", I );
}
If (indexPath. row> 3)
Cell. imageView. image = [UIImage imageNamed: @ "icon.png"];
Cell. textLabel. text = cellType;
Cell. detailTextLabel. text = @ "Subtitle text ";
Return cell;
}
The following describes how to reuse a queue:
Added elements of the multiplexing queue: the cell is added to the multiplexing queue only when the cell is sliding out of the interface. Each time a cell is created, the program first calls the dequeueReusableCellWithIdentifier: cellType method to find the cell with the identifier "cellType" in the multiplexing queue. If no cell is found, nil is returned, the program then calls [[[UITableViewCell alloc] initWithStyle: style reuseIdentifier: cellType] autorelease] to create a cell with the "cellType" identifier.
Run the program once. Do not slide the cell to view the print log. "cell create 1 times", "cell create 8 times" will be printed. There are 8 logs in total, this indicates that the cell is created eight times. The log is printed when the cell is created in cellForRowAtIndexPath. Next, slide the cell slowly (downward, in fact, by moving the hand up to display the next cell on the interface, and move it up to the opposite) until the ninth cell is displayed, the log "cell create 9 times" is printed, and then gradually slide down. "cell create 10 times" appears until after sliding to 12th cells, after 12 cells are created, the cells will not be created if they are slide in the future. In other words, this tableView requires complete work, and a total of 12 cells are created.
Explained the reason:
The interface on the first page needs to display a total of eight cells, so the cell needs to be created eight times, and each cell is responsible for displaying its own data. After the eight reuse queues are created, the reuse queue is still empty (because you have not sliding the cell yet, the elements of the reuse queue will not be added ). The cellForRowAtIndexPath method is also called when the first 9th cells are displayed sliding down. In this method, it is first found in the reusable queue because the queue is empty at this time, it creates a cell and prints logs. When the first cell slides out of the interface, the first cell enters the multiplexing queue, with an element in the queue, the identifier of this element is @ "Default Style ". Next, move down the cell and start to display 10th cells. It is also found in the multiplexing queue. The identifier of the 10th cells is @ "Subtitle Style ", however, the unique cell identifier in the queue is @ "Default Style", which is not found based on the identifier. Therefore, a new cell is created again, at the same time, 2nd cells slide out of the interface into the multiplexing queue. The multiplexing queue has two elements: @ "Default Style" and @ "Subtitle Style ". In the same way, when sliding to 11th cells, 3rd cells are in the queue and 12th cells are in the queue. The number of elements in the reuse queue is four, with the identifiers @ "Default Style", @ "Subtitle Style", @ "Value1 Style", @ "Value2 Style ". next, continue to slide the cell. When sliding to the first 13th cells, its identifier is @ "Default Style", which can be found in the multiplexing queue. Therefore, this cell will not be created. Similarly, sliding down again, all cells below can find the corresponding cell based on the identifier, and no cell will be created. During the sliding down process, the sliding cell will be queued, but only the created cell will be included, that is, there will be 12 cells in the final queue. Which of the following elements is used to obtain the corresponding identifier? What policies are adopted? I don't know about this. What I checked via print is to keep searching for the queue while sliding down. The queue is a circular queue. When sliding up, it looks up against the queue. As it is a cyclic queue, it is always in a circle.
If you take a closer look, you will find that there is no image in the first cell. Why do you slide it and slide it again? (If the sliding distance is far, you can do it once. If the sliding distance is close, how many times does one slide up or down? We need to think about one thing: when the first cell slides out of the interface and is inserted into the interface, it is obtained from the multiplexing queue. The multiplexing queue has 12 elements, and the first cell has the same identifier, 1st without images, and 5th and 9th with images. When users reuse the first cell, there is no image. When users reuse the fifth or ninth cell, there is an image. Therefore, when you slide up and down to view the first cell, you will see that it will have an image while there will be no image. This is related to the queue Search rules during reuse.
Practical:
I have said so much about the principles. It is practical now. If you want to add a button to all cells, should you add the button in if or outside of if? There is no doubt that it should be in if. if you add it outside of if, it will lead to the process of sliding down the cell, and the obtained cell already has a button, while you are still in addSubview, there are more and more buttons. Alternatively, you can add them outside the if clause, provided that all the child views of the cell are removed each time. This consumes too much cpu and is troublesome. What should you do if you want to have buttons and no buttons in one row? Think for a moment, this is a two-style cell, so they should belong to different identifiers when sliding out the interface for reuse. Therefore, when creating a cell, you should specify two identifiers to create two types of cells. Of course, maybe you are smart. can I remove all the child views of the cell out of if, and then use row % 2 = 0 or! = 0 for addSubView: button? The answer is yes, of course, but it is still the same problem, which consumes too much cpu. We usually add a button to each cell. We must add events. For different buttons, how does one respond to different events? In this case, do I set its tag (for example, button. tag = indexpath. row) for the button in the if statement? Haha, you should be smart enough. Of course not. You can think like this, the if statement is used to create, it is only executed (for example, the above example: 12 times), but you may have hundreds of lines of cells, of course, you only have 12 tags, which obviously do not match. What should I do for something like this? The answer is: put it outside of if. You have set tag tags outside if. Of course, there are still only 12 tags at a specific time point, but these 12 tags are variable, for example, if cell-is displayed on the current page, the tag of the button will be-, and 12 buttons will still be displayed, but they will slide according to the user, different tag switching is equivalent to having many buttons. If you are not dizzy with what I have said, and your head is sober enough, you can come to the following conclusion: it is better to customize the interface in if, A cell is created only once. For data customization, it is better to put it outside of if. For different cells, it indicates different content, although there are only 12 cells, however, I can map the data stored in the cell as needed. If you come to this conclusion, you can easily add textField, label, and so on. Not only on the surface, but more importantly, you understand the principle, master the mechanism, and are not afraid of anything. Even if you have new requirements, think about it, or take a look at this article, hope to give you some inspiration.
Author: lipeng08