2014-10-10 65 views
0

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

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

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

我想到:

  • KVO数据源的数据,并且当其被执行每次在数据源中的数据的变化的阵列变化呼叫reloadData
  • 移交的块(具有[self.table reloadData])到数据源
  • 在ViewController上公开表的属性,这样DataSource可以调用reloadData(我不太喜欢这个想法)
  • 在DataSource上有一个属性, ViewController与表使用它作为代表(这听起来像一个循环)

有没有什么聪明的方法来做到这一点?甚至常见的做法如何解决这个问题?

更新:

我不感兴趣的代码怎么办实施了一定的设计模式。我更感兴趣的是为什么要选择另一种模式。

+0

如果你想保持相关数据的代码独立的,为什么不是你的视图控制器上创建一个类别说'MyTableVC + DataSource'什么的?这会工作吗?或者你真的希望另一个班级成为数据源? – GoodSp33d 2014-10-10 17:02:38

+0

@ GoodSp33d不适用于我,因为我想将不同的数据源插入VC以从不同的端点/核心数据请求获取不同的数据 – hashier 2014-10-11 09:04:39

+0

好吧,您正在寻找重用您的VC。然后按照其他人的建议,创建一个接口(协议)并在通常的表格数据源中调用这些方法。其他类可以在协议中实现这些方法,以便将数据提供给VC – GoodSp33d 2014-10-11 09:21:15

回答

2

没有更多的细节,这听起来像你需要在这里回调。有几种方法可以工作。如果你有1对1的关系(意思是你的dataSource只需要跟VC通话),那么这是一个很好的情况:

1.)一个委托。为你的dataSource创建你自己的委托协议,然后让VC坚持该协议(成为委托)。

2.)使用回调块进行同样的操作。

KVO也可以正常工作,但上述两个更符合您的情况。

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

+0

您能否详细说明为什么您认为代表是比KVO更好的设计? – hashier 2014-10-11 13:09:06

+1

在这种情况下使用回调vs KVO将您的课程更紧密地结合在一起,并且更具可读性。您可以控制委托人何时被解雇,但是如果使用KVO,您的观察员将随时在其订阅者变更时被调用。也许你不希望你的tableView重新加载有时会改变它的数据源。假设您使用KVO来订阅NSMUtableArray上的更改,每次向该数组添加对象时,都会通知您的侦听器。你可能想要的是在最后一个对象被添加到你的数组之后通知你的监听器,因此只刷新一次你的tableView。 – VaporwareWolf 2014-10-11 18:04:34

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 
+0

感谢您的代码,但我的主要问题是为什么要选择其他方法的委托?我对设计更感兴趣,而不是最终如何实现设计。 – hashier 2014-10-11 09:09:04

+0

它有助于划分代码,但它也使得流程更加明确。当使用'NSNotificationCenter'时,你有点打破了这条链。它不仅使代码更难以跳过(没有热键关注通知流程),但调试器不会列出原始堆栈跟踪。 – 2014-10-14 13:27:17

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]; 
} 
+0

感谢您的代码,但我的主要问题是为什么选择通知其他方法?我对设计更感兴趣,而不是如何最终实现设计 – hashier 2014-10-11 09:09:43

+0

@hashier当您使用通知来表示关系而不是协议时,对象会非常松散地相互耦合。这意味着当事情发生变化时,通常会这样做,修改此代码很容易。坦率地说,像tableview数据源和视图控制器之类的关系通常不足以保证协议定义,而在Objective-C中,以这种方式维护这些关系非常繁琐。 – markshiz 2014-10-12 18:18:21

+0

@hashier例如,使用'NSNotificationCenter'添加参数和删除参数不需要更改现有代码的代码,而委托需要重新定义协议,所有实现方法和所有测试。 – markshiz 2014-10-12 18:22:09

相关问题