有时候我们的控制器会非常庞大,一部分原因就是控制器要获取数据,可能包含从网络中加载数据,这时候我们需要把获取dataSource这部分代码分离出来,创建一个新的类。
1. tableView分离dataSource
分离UITableViewController中的dataSource到一个单独的类,并实现UITableViewDataSource协议及其方法。
ArrayDataSource.h
typedef void (^TableViewCellConfigureBlock)(id cell, id item);
@interface ArrayDataSource : NSObject <UITableViewDataSource>
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock;
- (id)itemAtIndexPath:(NSIndexPath *)indexPath;
@end
ArrayDataSource.m
@interface ArrayDataSource ()
@property (nonatomic, strong) NSArray *items;
@property (nonatomic, copy) NSString *cellIdentifier;
@property (nonatomic, copy) TableViewCellConfigureBlock configureCellBlock;
@end
@implementation ArrayDataSource
- (id)init
{
return nil;
}
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock
{
self = [super init];
if (self) {
self.items = anItems;
self.cellIdentifier = aCellIdentifier;
self.configureCellBlock = [aConfigureCellBlock copy];
}
return self;
}
- (id)itemAtIndexPath:(NSIndexPath *)indexPath
{
return self.items[(NSUInteger) indexPath.row];
}
#pragma mark UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier
forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
self.configureCellBlock(cell, item);
return cell;
}
@end
使用该dataSource,只需要initWithItems即可,并把该dataSource赋值给tableView.dataSource
- (void)setupTableView
{
TableViewCellConfigureBlock configureCell = ^(PhotoCell *cell, Photo *photo) {
[cell configureForPhoto:photo];
};
NSArray *photos = [AppDelegate sharedDelegate].store.sortedPhotos;
self.photosArrayDataSource = [[ArrayDataSource alloc] initWithItems:photos
cellIdentifier:PhotoCellIdentifier
configureCellBlock:configureCell];
self.tableView.dataSource = self.photosArrayDataSource;
[self.tableView registerNib:[PhotoCell nib] forCellReuseIdentifier:PhotoCellIdentifier];
}
2. 从UIViewController中分离网络请求
单独定义一个UIViewControllerData类,实现网络请求。该类实现UIViewController中定义的协议,在指定时刻去加载数据,进行网络请求,并把获取的数据通过调离的block返回给控制器,控制器在进行其他操作(如tableView reload)
.h
@interface UIViewControllerData : NSObject <RefreshableListViewControllerDataSource>
+ (instancetype)sharedInstance;
@end
.m
@implementation UIViewControllerData
+ (instancetype)sharedInstance {
static UIViewControllerData *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[UIViewControllerData alloc] init];
});
return instance;
}
- (void)refreshableListViewController:(RefreshableListViewController *)controller loadDataFrom:(NSUInteger)offset limit:(NSUInteger)limit withUserToken:(NSString *)token completion:(void (^)(NSArray *, BOOL))completionBlock fail:(void (^)(NSError *))failBlock {
//网络请求数据
[UserAPI query:param userToken:token completion:^(NSArray<UserProfileSimplify> *userProfiles, BOOL hasMore) {
if (completionBlock) {
completionBlock(userProfiles,hasMore);
}
} error:^(ServerAPIError *error) {
DDLogDebug(@"---MYLOG:出错啦!---");
}];
} error:failBlock];
}
@end