UITableView is one of the most commonly used components in the development, and MY habit is that even the simplest Cell will be customized. As for the reuse writing method, the official gave us two ways to write, one is to register the Cell needed when creating TableView, and call it in the proxy DequeueReusableCellWithIdentifier method, if not reuse the Cell will automatically go initialization method, we also custom content by rewriting the methods to achieve it, another method is not registered, in judgment about the agent DequeueReusableCellWithIdentifier this method returns the object is null, if is empty to create manually, these two methods to use most, but more to go into their writing. So here are my two problems with binding.

1. If two or more TableViews are added to a View, can the two TableViews be bound to the same identifier? Will there be a problem? This problem has not been too attention, because at the beginning of writing TableView, master said that each TableView bound to the same identifier , before also read some articles that write this will appear error, has been written like this, until now feel troublesome, each time to define a variable, although you can get the class name to define the variable, but ultimately will write a few lines of code Add two TableViews to the controller, each occupying half of the screen. The identifier on the left is LQTableViewCell. The identifier on the left is LQTableViewCell LQTableViewCell and LQTableViewCell4. These two tableViews have a common identifier(LQTableViewCell).

    _mTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
    _mTableView.delegate = self;
    _mTableView.dataSource = self;
    _mTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    _mTableView.backgroundColor = UIColor.clearColor;
    _mTableView.showsVerticalScrollIndicator = NO;

    [_mTableView registerClass:[LQTableViewCell class] forCellReuseIdentifier:@"LQTableViewCell"];


    [self.view addSubview:self.mTableView];
    [self.mTableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view).offset(NavigationContentTop);
        make.bottom.equalTo(self.view).offset(-34);
        make.left.equalTo(self.view);
        make.width.mas_equalTo(SCREEN_WIDTH/2.f - 5);
    }];

    _nTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
    _nTableView.delegate = self;
    _nTableView.dataSource = self;
    _nTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    _nTableView.backgroundColor = UIColor.clearColor;
    _nTableView.showsVerticalScrollIndicator = NO;

    [_nTableView registerClass:[LQTableViewCell2 class] forCellReuseIdentifier:@"LQTableViewCell"];
    [_nTableView registerClass:[LQTableViewCell4 class] forCellReuseIdentifier:@"LQTableViewCell4"];
    
    _nTableView.tag = 88;

    [self.view addSubview:_nTableView];
    
    [self.nTableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.top.bottom.equalTo(self.view);
        make.left.equalTo(self.mTableView.mas_right).offset(10);
        
    }];
    
    self.view.backgroundColor = UIColor.qmui_randomColor;
Copy the code

After the basic setup, see the implementation in the proxy

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView.tag == 88) { if (indexPath.row % 2 ! = 0) { LQTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LQTableViewCell"]; Cell.textlabel. text = [NSString stringWithFormat:@"%d- single line ",(int)indexPath. Row]; return cell; }else{ LQTableViewCell4 *cell = [tableView dequeueReusableCellWithIdentifier:@"LQTableViewCell4"]; Cell.lb. text = [NSString stringWithFormat:@"%d- double row ",(int)indexPath. Row]; return cell; } }else{ LQTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LQTableViewCell"]; cell.textLabel.text = [NSString stringWithFormat:@"%d",(int)indexPath.row]; return cell; } return UITableViewCell.new; }Copy the code

After running is completely no problem, through the interrupt point debugging, after all reuse, will not call the initialization method of TableViewCell, indicating reuse

2. Based on the first question, we began to consider whether in a project, we could write a method to make use of OC polymorphisms, and then directly assign values to the Cell every time we instantiate the Cell, so as to reduce the amount of code in the Controller, and make use of the uniqueness of the class name instead of defining a identifier variable every time How many, are for their own lazy excuses. Create a new base class for TableViewCell and define a class method


+ (id)cellWithTableView:(UITableView *)tableView andIndexPath:(NSIndexPath *)indexPath subClass:(Class)subClass;

Copy the code

Then implement the class method

+ (id)cellWithTableView:(UITableView *)tableView andIndexPath:(NSIndexPath *)indexPath subClass:(nonnull Class)subClass{  [tableView registerClass:[self class] forCellReuseIdentifier:NSStringFromClass(subClass)]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(subClass) forIndexPath:indexPath]; return cell; }Copy the code

Then call this method when creating the TableviewCell, pass in the subClass and TableView to register our custom Cell for the current TableView, and use the same UI as above to bind the identifier

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView.tag == 88) { if (indexPath.row % 2 ! = 0) { LQTableViewCell *cell = [LQTableViewCell cellWithTableView:tableView andIndexPath:indexPath subClass:LQTableViewCell.class]; Cell.textlabel. text = [NSString stringWithFormat:@"%d- single line ",(int)indexPath. Row]; return cell; }else{ LQTableViewCell4 *cell = [LQTableViewCell4 cellWithTableView:tableView andIndexPath:indexPath subClass:LQTableViewCell4.class]; Cell.lb. text = [NSString stringWithFormat:@"%d- double row ",(int)indexPath. Row]; return cell; } }else{ LQTableViewCell *cell = [LQTableViewCell cellWithTableView:tableView andIndexPath:indexPath subClass:LQTableViewCell.class]; cell.textLabel.text = [NSString stringWithFormat:@"%d",(int)indexPath.row]; return cell; } return UITableViewCell.new; }Copy the code

Run,no problem.

Then I will talk about the problems of this method and the test I did. The problem of this method is that every time I go through the TableView proxy, the same identifier will be repeatedly registered. If it is simply a repeat problem, it is ok, but I worry about the performance problems caused by too many cells. I returned 1000 cells using the official recommended method and this method, and then slid them at roughly the same speed, observing memory and CPU as a result Since the TableView manages the reuse of the Cell, it should handle the situation of repeated registration, otherwise the annotation will warn us not to repeat registration of the same identifier, so the preliminary guess should not cause performance problems, may also cause performance problems I haven’t found it.