将信息从UITableViewDataSource传递回ViewController

时间:2014-10-10 16:25:41

标签: ios objective-c uitableview

我有一个带有UITableView的ViewController。由于我想拆分数据处理,我创建了一个自己的类来回答UITableViewDataSource。

这个类应该首先从CoreData中获取数据,然后从REST API中获取数据。

DataSource如何与ViewController对话以告诉它在TableView上调用reloadData? 这里的最佳做法是什么?

我想到了:

  • KVO数据源的数据以及数组更改时的调用reloadData
  • 将一个块([self.table reloadData])移交给DataSource,每次DataSource中的数据发生变化时都会执行该操作
  • 在ViewController上公开table属性,以便DataSource可以调用reloadData(我不喜欢这个想法)
  • 在DataSource上有一个属性,它将ViewController与Table一起用作委托(这听起来像一个循环)

有没有聪明的方法呢?甚至常见的做法如何解决这个问题?

更新

我对代码不太感兴趣,如何实现某种设计模式。我对为什么选择一种模式而不是另一种模式的理由更感兴趣。

3 个答案:

答案 0 :(得分:2)

没有更多细节,听起来你需要回调。有几种方法可行。如果你有一对一的关系(意味着你的dataSource只需要与VC交谈),那么这是一个很好的例子:

1。)代表。为您的dataSource创建自己的委托协议,然后让VC遵守该协议(作为委托)。

2。)使用块进行回调,做同样的事情。

KVO也会很好用,但上面两个更符合你的情景。

可以将tableView属性添加到您的自定义数据源,但这会模糊您首先创建该类的原因。

答案 1 :(得分:1)

对于这样的情况,我更喜欢代表。

@class CupcakePan;

@protocol CupcakePanDelegate <NSObject>
- (void)cupcakesAreReadyForPan:(CupcakePan *)pan;
@end

@interface CupcakePan : NSObject <UITableViewDataSource>
@property (weak) id<CupcakePanDelegate> delegate;
@end

@implementation CupcakePan
- (void)bakingComplete {
  [self.delegate cupcakesAreReadyForPan:self];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  return [cupcakes count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  return [make a CupcakeCell];
}
@end

@interface CupcakeViewController <CupcakePanDelegate>
@end

@implementation CupcakeViewController
- (void)cupcakesAreReadyForPan:(CupcakePan *)pan {
  [_tableView reloadData];
}
@end

答案 2 :(得分:0)

我经常使用NSNotificationCenter进行这些类型的互动。

在您的数据源中编写以下代码:

#define ABCNotificationName @"ABCNotificationName"
#define ABCNotificationData @"ABCNotificationData"

// ...

[[NSNotificationCenter defaultCenter] postNotificationName:ABCNotificationName object:self userInfo:@{ ABCNotificationData: data }];

在视图控制器中执行以下操作:

-(void)loadView {
    // setup your view
    [NSNotificationCenter defaultCenter] addObserver:self selector:@selector(datasourceUpdated:) name:ABCNotificationName object:dataSource];
}

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(void)dataSourceUpdated:(NSNotification*)notification {
    id data = notification.userInfo[ABCNotificationData]; 
    // respond to the event
    [self.tableView reloadData];
}

请注意,如果您没有任何数据可以与控制器进行通信,那就更容易了。在您的数据源中编写以下代码:

#define ABCNotificationName @"ABCNotificationName"

// ...

[[NSNotificationCenter defaultCenter] postNotificationName:ABCNotificationName object:self];

在视图控制器中执行以下操作:

-(void)loadView {
    // setup your view
    [NSNotificationCenter defaultCenter] addObserver:self selector:@selector(datasourceUpdated) name:ABCNotificationName object:dataSource];
}

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(void)dataSourceUpdated {
    // respond to the event
    [self.tableView reloadData];
}