iOS Development UI Chapter-uitableviewcell performance issues
First, some introduction of UITableViewCell
Each line of the UITableView is a UITableViewCell, initialized by DataSource's Tableview:cellforrowatindexpath: method to initialize each row
There is a default child view inside the UITableViewCell: Contentview,contentview is the parent view of the content displayed by the UITableViewCell, which displays some auxiliary indication views
The work of the auxiliary indicator view is to display an icon that represents an action, which can be displayed by setting the Accessorytype of the UITableViewCell, which is the default is Uitableviewcellaccessorynone (does not show the auxiliary reference), The other values are as follows:
Uitableviewcellaccessorydisclosureindicator
Uitableviewcellaccessorydetaildisclosurebutton
Uitableviewcellaccessorycheckmark
You can also customize the secondary indicator view by using the cell's Accessoryview property (?) by placing a switch to the right.
Second, the question
Cell work: When the program executes, you can see how many bars it creates, and if the view scrolls, then create the new display. (System calls automatically). That is, when a cell appears within the field of view, it is called to create a cell. This logic seems to be fine, but is there really no problem?
When the call is created, we use NSLog to print the message and print the address of the cell that was created. We found that if the amount of data is very large and the user scrolls back and forth in a short period of time, then a large number of cells will be created, and if it is a rollback, by printing the address, we will find that it does not reuse the cell created before, but instead re-creates it and opens up new storage space.
Is there any good solution?
Third, the principle of cell reuse
(1) iOS devices have limited memory, and if you use UITableView to display thousands of data, you need thousands of UITableViewCell objects, which will deplete the memory of your iOS device. To work around this problem, you need to reuse the UITableViewCell object
(2) Principle: When scrolling the list, some UITableViewCell will move out of the window, and UITableView will place the UITableViewCell outside the window into an object pool for reuse. When UITableView requires DataSource to return UITableViewCell, DataSource will look at the object pool first, if there are unused uitableviewcell in the pool, DataSource will use the new data to configure the UITableViewCell, and then return to the UITableView, re-display to the window, avoiding the creation of new objects. This allows the number of cells created to be kept at a very low level, and if only 5 cells are displayed in a single window, then after the cell is reused, it is sufficient to create only 6 cells.
(3) Note: There is a very important question: Sometimes you need to customize the UITableViewCell (with the. Subclass inheritance UITableViewCell), and each line is not necessarily the same kind of uitableviewcell, so a A uitableview may have different types of uitableviewcell, and there will be many different types of UITableViewCell in the object pool, so UITableView may get the wrong type when using UITableViewCell. UITableViewCell
Solution: UITableViewCell has a nsstring *reuseidentifier property that allows you to set reuseidentifier by passing in a specific string identifier when initializing UITableViewCell ( Generally used UITableViewCell class name). When UITableView requires DataSource to return UITableViewCell, a string is first identified to the object pool to find the corresponding type of UITableViewCell object, if there is, reuse, if not, pass the string identifier to initialize ? a UITableViewCell object.
Image examples:
Note: A window can be placed under (visible) three cells, the entire program only need to create 4 of this type of cell.
Iv. optimized code for cell
code example:
1 #import "NJViewController.h" 2 #import "NJHero.h" 3 4 //#define ID @ "ABC" 5 6 @interfaceNjviewcontroller () <uitableviewdatasource, uitableviewdelegate>7 /** 8 * Save all hero Data 9*/Ten@property (nonatomic, strong) Nsarray *heros; One@property (Weak, nonatomic) iboutlet UITableView *TableView; A - @end - the @implementationNjviewcontroller - - #pragmaMark-Lazy Loading --(Nsarray *) Heros + { - if(_heros = =Nil) { + //1. Get the full path ANSString *fullpath = [[NSBundle mainbundle] Pathforresource:@"heros"OfType:@"plist"]; at //2. More full path loading data -Nsarray *dictarray =[Nsarray Arraywithcontentsoffile:fullpath]; - //3. Dictionary Turn Model -Nsmutablearray *models =[Nsmutablearray ArrayWithCapacity:dictArray.count]; - for(Nsdictionary *dictinchDictarray) { -Njhero *hero =[Njhero herowithdict:dict]; in[Models Addobject:hero]; - } to //4. Assigning Data +_heros =[models copy]; - } the //4. Return Data * return_heros; $ }Panax Notoginseng -- (void) Viewdidload the { +[Super Viewdidload]; A //Set the cell height the //use the property to set the cell height when the cell height of each row is consistent +Self.tableView.rowHeight = the; - } $ $ #pragmaMark-uitableviewdatasource - //How many groups are returned --(Nsinteger) Numberofsectionsintableview: (UITableView *) TableView the { - return 1;Wuyi } the //returns how many rows each group has --(Nsinteger) TableView: (UITableView *) TableView numberofrowsinsection: (nsinteger) section Wu { - returnSelf.heros.count; About } $ //when a cell appears in the field of view, it is called - //returns which line of a group shows what --(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) Indexpath - { A //define variables to hold values for reuse tags + StaticNSString *identifier =@"Hero"; the - //1. First go to the cache pool to find out if there are any cells that meet the criteria $UITableViewCell *cell =[TableView Dequeuereusablecellwithidentifier:identifier]; the //2. If there is no qualifying cell in the cache pool, create a cell of your own the if(Cell = =Nil) { the //3. Create a cell and set a unique tag theCell =[[UITableViewCell alloc] Initwithstyle:uitableviewcellstylesubtitle reuseidentifier:identifier]; -NSLog (@"Create a new cell"); in } the //4. Set Data to cell theNjhero *hero =Self.heros[indexpath.row]; AboutCell.textLabel.text =Hero.name; theCell.detailTextLabel.text =Hero.intro; theCell.imageView.image =[UIImage ImageNamed:hero.icon]; the + //NSLog (@ "%@-%d-%p", Hero.name, Indexpath.row, cell); - the //3. Return to cellBayi returncell; the } the - #pragmaMark-Controls whether the status bar is displayed - /**86 * Returns yes for hidden status bar, no opposite*/ the-(BOOL) Prefersstatusbarhidden the { - returnYES; the } the @end
The idea of cache optimization:
(1) First go to the cache pool to find if there is a cell that satisfies the condition, if there is, take it directly.
(2) If not, create a cell yourself
(3) Create a cell, and set a unique tag (the one that belongs to "" to cover a chapter)
(4) Set data to cell
Note the point:
Defining a variable to hold the value of the reuse tag is not recommended here (#define来处理), because the variable is used only within the scope, and if the macro definition is used, the definition and use of the location are too fragmented to read the program. Since its value is constant, it is not necessary to open it every time, so it is defined as a static variable with static.
iOS Development UI Chapter-uitableviewcell performance issues