I'm trying to create a class cluster for a UITableViewDatasource. My interface looks like this:
@interface ArrayDataSource : NSObject <UITableViewDataSource>
- (id)initWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier configureCellBlock:(TableViewCellConfigureBlock)configurationBlock;
- (id)initWith2DArray:(NSArray *)array sectionIdentifiers:(NSArray *)cellIdentifiers configureCellBlock:(TableViewCellConfigureBlock)configurationBlock;
- (id)itemAtIndexPath:(NSIndexPath *)indexPath;
@end
Internally, the abstract class looks like this:
@implementation ArrayDataSource
- (id)initWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier configureCellBlock:(TableViewCellConfigureBlock)configurationBlock {
return [[SingleArrayDatasource alloc] initWithItems:items cellIdentifier:cellIdentifier configureCellBlock:configurationBlock];
}
- (id)initWith2DArray:(NSArray *)array sectionIdentifiers:(NSArray *)cellIdentifiers configureCellBlock:(TableViewCellConfigureBlock)configurationBlock {
return [[TwoDimensionalArrayDatasource alloc] initWith2DArray:array sectionIdentifiers:cellIdentifiers configureCellBlock:configurationBlock];
}
Now, in order to silence the compiler, who is complaining that the abstract class (ArrayDatasource) doesn't implement the uitableview datasource required methods, i've added these:
#pragma mark - Overrides
- (id)itemAtIndexPath:(NSIndexPath *)indexPath { return nil; }
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 0; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 0; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { return nil; }
But whenever I use the cluster, the datasource method calls go to the abstract class! If i delete those overrides, everything works as desired (except i still have the compiler warning).
What is going on? Why are those messages going to the abstract class when the instance is a SingleArrayDatasource
or a TwoDimentionalArrayDatasource
?
UPDATE
here is how I implemented one of the concrete subclasses
@implementation SingleArrayDatasource
- (id)initWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier configureCellBlock:(TableViewCellConfigureBlock)configurationBlock
{
self = [super init];
if (self) {
self.items = items;
self.cellIdentifier = cellIdentifier;
self.configureCellBlock = [configurationBlock copy];
}
return self;
}
- (id)itemAtIndexPath:(NSIndexPath *)indexPath
{
return self.items[indexPath.row];
}
#pragma mark UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
id cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
self.configureCellBlock(cell, item);
return cell;
}
One thing you have to do is in your concrete subclasses, no need to call super init, as you are already calling alloc, which will do the memory allocation. Also, in your abstract class, before calling concrete class initialisation method set self to nil, so that there won't be any trace of abstract class. Once you do that you don't need to delete the over rides.