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

如何实现两个Table View间的数据共享与实时同步?

嘿,这个场景我太熟了!要让两个TableView实时同步数据,核心就是让它们共享同一个数据源,同时在数据变化时能及时通知到两个视图。我给你几个实用的方案,按推荐程度排序👇

最推荐:单例数据管理器(解耦+统一管理)

把共享的可变数组放到一个全局唯一的单例类里,这个类专门负责数据的增删改查,两个TableViewController都从这里获取数据源。这样做的好处是数据逻辑和视图完全分离,所有数据操作都集中管理,不会出现多个地方改数组导致的不一致问题。

步骤1:创建数据管理器类

先建一个DataManager类(.h和.m文件),封装数组和操作方法:

// DataManager.h
#import <Foundation/Foundation.h>
@class YourCustomObject; // 替换成你的自定义对象类名

@interface DataManager : NSObject
// 只读属性,外部只能通过封装的方法修改数组
@property (nonatomic, strong, readonly) NSMutableArray<YourCustomObject *> *objects;

// 获取单例实例
+ (instancetype)sharedManager;

// 封装数据操作方法
- (void)addCustomObject:(YourCustomObject *)object;
- (void)removeCustomObject:(YourCustomObject *)object;
- (void)moveObjectFromIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex;
@end
// DataManager.m
#import "DataManager.h"
#import "YourCustomObject.h"

static DataManager *_sharedInstance = nil;

@implementation DataManager

+ (instancetype)sharedManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
        _sharedInstance.objects = [NSMutableArray array];
    });
    return _sharedInstance;
}

- (void)addCustomObject:(YourCustomObject *)object {
    // 加个同步锁,避免多线程操作数组出问题
    @synchronized(self) {
        [self.objects addObject:object];
    }
    // 发送通知,告诉所有监听的视图数据更新了
    [[NSNotificationCenter defaultCenter] postNotificationName:@"CustomObjectsUpdated" object:nil];
}

- (void)removeCustomObject:(YourCustomObject *)object {
    @synchronized(self) {
        [self.objects removeObject:object];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"CustomObjectsUpdated" object:nil];
}

- (void)moveObjectFromIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex {
    @synchronized(self) {
        if (fromIndex != toIndex && fromIndex < self.objects.count && toIndex < self.objects.count) {
            YourCustomObject *targetObj = self.objects[fromIndex];
            [self.objects removeObjectAtIndex:fromIndex];
            [self.objects insertObject:targetObj atIndex:toIndex];
        }
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"CustomObjectsUpdated" object:nil];
}

@end

步骤2:在TableViewController里使用

每个TableViewController都注册通知、获取共享数据源,数据变化时自动刷新:

#import "DataManager.h"

@implementation YourTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 注册通知,监听数据更新
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(refreshTableView) 
                                                 name:@"CustomObjectsUpdated" 
                                               object:nil];
    // 绑定共享数据源
    self.dataSourceArray = [DataManager sharedManager].objects;
}

- (void)refreshTableView {
    // 一定要在主线程刷新UI
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
}

// 记得在销毁时移除观察者,避免野指针
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

// 剩下的TableView代理方法就用self.dataSourceArray作为数据源即可
@end
备选方案:AppDelegate存放数组(不推荐)

你也可以把可变数组放到AppDelegate的属性里,两个TableViewController通过[[UIApplication sharedApplication] delegate]获取这个数组。但这种方法会让AppDelegate变得臃肿,视图和AppDelegate耦合度太高,后期维护起来很麻烦,只适合极小的Demo项目,不推荐在正式项目里用。

另一种思路:KVO监听数组变化

如果不想用通知,可以让TableViewController监听单例里数组的变化。不过要注意:普通的NSMutableArray增删改不会触发KVO,因为KVO监听的是属性的setter方法。所以你需要在DataManager的操作方法里手动触发KVO通知:

// 在DataManager的add方法里修改
- (void)addCustomObject:(YourCustomObject *)object {
    @synchronized(self) {
        [self willChangeValueForKey:@"objects"];
        [self.objects addObject:object];
        [self didChangeValueForKey:@"objects"];
    }
}

然后在TableViewController里监听:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.dataManager = [DataManager sharedManager];
    [self.dataManager addObserver:self 
                      forKeyPath:@"objects" 
                         options:NSKeyValueObservingOptionNew 
                         context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change 
                       context:(void *)context {
    if ([keyPath isEqualToString:@"objects"]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView reloadData];
        });
    }
}

- (void)dealloc {
    [self.dataManager removeObserver:self forKeyPath:@"objects"];
}

这种方法也能实现同步,但通知的写法更直观,KVO需要注意处理上下文和避免内存泄漏,看你个人习惯选择。


内容的提问来源于stack exchange,提问作者John L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:18:02