You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在一个类中实现两个拥有不同代理与数据源方法的TableView?

嘿,这个问题我之前帮不少iOS开发者捋清过思路——Objective-C确实不支持方法重载,但要在同一个类里搞定两个参数类型不同的TableView,咱们有好几招实用的办法:

解决同一个类中多TableView参数类型不同的问题

方法一:给TableView设置Tag区分

这是最常用的入门方案,先给两个TableView分别设置唯一的Tag值,然后在代理/数据源方法里通过判断Tag来分支处理不同参数类型的逻辑。

比如初始化TableView时:

// 第一个处理NSString类型数据的TableView
UITableView *stringTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
stringTableView.tag = 1001;
stringTableView.dataSource = self;
stringTableView.delegate = self;
[self.view addSubview:stringTableView];

// 第二个处理NSNumber类型数据的TableView
UITableView *numberTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 220, self.view.frame.size.width, 200)];
numberTableView.tag = 1002;
numberTableView.dataSource = self;
numberTableView.delegate = self;
[self.view addSubview:numberTableView];

然后在数据源方法里分支:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (tableView.tag == 1001) {
        return self.stringDataArray.count; // NSString类型数组
    } else if (tableView.tag == 1002) {
        return self.numberDataArray.count; // NSNumber类型数组
    }
    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (tableView.tag == 1001) {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"StringCell" forIndexPath:indexPath];
        NSString *item = self.stringDataArray[indexPath.row];
        cell.textLabel.text = item;
        return cell;
    } else if (tableView.tag == 1002) {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"NumberCell" forIndexPath:indexPath];
        NSNumber *item = self.numberDataArray[indexPath.row];
        cell.textLabel.text = [item stringValue];
        return cell;
    }
    return [[UITableViewCell alloc] init];
}

方法二:直接判断TableView实例

如果你的两个TableView是类的属性,直接判断实例会比Tag更直观,避免Tag值冲突的问题。

先在类的头文件里声明属性:

@property (nonatomic, strong) UITableView *stringTableView;
@property (nonatomic, strong) UITableView *numberTableView;

初始化时赋值:

self.stringTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
self.stringTableView.dataSource = self;
self.stringTableView.delegate = self;
[self.view addSubview:self.stringTableView];

self.numberTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 220, self.view.frame.size.width, 200)];
self.numberTableView.dataSource = self;
self.numberTableView.delegate = self;
[self.view addSubview:self.numberTableView];

然后在代理方法里判断实例:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (tableView == self.stringTableView) {
        // 处理NSString类型数据的逻辑
        NSString *item = self.stringDataArray[indexPath.row];
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"StringCell" forIndexPath:indexPath];
        cell.textLabel.text = item;
        return cell;
    } else if (tableView == self.numberTableView) {
        // 处理NSNumber类型数据的逻辑
        NSNumber *item = self.numberDataArray[indexPath.row];
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"NumberCell" forIndexPath:indexPath];
        cell.textLabel.text = [item stringValue];
        return cell;
    }
    return [[UITableViewCell alloc] init];
}

方法三:给TableView绑定对应的数据模型(更优雅的方案)

如果不想写一堆判断分支,可以用Objective-C的关联对象,给每个TableView直接绑定对应的数据数组,这样在代理方法里直接取出数据,根据数据类型处理即可。

首先导入头文件:

#import <objc/runtime.h>

初始化TableView时绑定数据:

UITableView *stringTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
stringTableView.dataSource = self;
stringTableView.delegate = self;
// 绑定字符串数组到TableView
objc_setAssociatedObject(stringTableView, @selector(boundDataArray), self.stringDataArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self.view addSubview:stringTableView];

UITableView *numberTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 220, self.view.frame.size.width, 200)];
numberTableView.dataSource = self;
numberTableView.delegate = self;
// 绑定数字数组到TableView
objc_setAssociatedObject(numberTableView, @selector(boundDataArray), self.numberDataArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self.view addSubview:numberTableView];

然后在代理方法里取出数据处理:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSArray *dataArray = objc_getAssociatedObject(tableView, @selector(boundDataArray));
    return dataArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *dataArray = objc_getAssociatedObject(tableView, @selector(boundDataArray));
    id item = dataArray[indexPath.row];
    
    if ([item isKindOfClass:[NSString class]]) {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"StringCell" forIndexPath:indexPath];
        cell.textLabel.text = item;
        return cell;
    } else if ([item isKindOfClass:[NSNumber class]]) {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"NumberCell" forIndexPath:indexPath];
        cell.textLabel.text = [item stringValue];
        return cell;
    }
    
    return [[UITableViewCell alloc] init];
}

小建议

  • 如果只是两个简单的TableView,用Tag或者直接判断实例就足够简单高效;
  • 如果后续可能扩展更多TableView,或者想让代码更解耦,绑定数据模型的方案会更优雅,不用修改代理方法里的判断逻辑。

内容的提问来源于stack exchange,提问作者Mehdi Negahban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:18:25