在目标c中创建一个类集群 - 在抽象超类上调用的方法?

时间:2014-04-23 22:25:23

标签: ios objective-c class-cluster

我正在尝试为UITableViewDatasource创建一个类集群。我的界面如下所示:

@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

在内部,抽象类看起来像这样:

@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];
}

现在,为了让编译器保持沉默,谁抱怨抽象类(ArrayDatasource)没有实现uitableview数据源所需的方法,我已经添加了这些:

#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; }

但每当我使用集群时,数据源方法调用都会转到抽象类!如果我删除那些覆盖,一切都按预期工作(除了我仍然有编译器警告)。

发生了什么事?当实例为SingleArrayDatasourceTwoDimentionalArrayDatasource时,为什么这些消息会转到抽象类?

更新

这是我如何实现其中一个具体的子类

@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;
}

2 个答案:

答案 0 :(得分:0)

你的问题正在发生,因为Objective C确实没有抽象类型,至少不像Java那样。

此外,您从init返回一个变形类型,它们是实例方法,这意味着您必须已经在&#34;抽象类型&#34;的实例上运行。 - 这是不合逻辑的。

我建议你在&#34;抽象类&#34;中使用工厂模式。 -

@implementation ArrayDataSource

+ (id)dataSourceWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier configureCellBlock:(TableViewCellConfigureBlock)configurationBlock {
    return [[SingleArrayDatasource alloc] initWithItems:items cellIdentifier:cellIdentifier configureCellBlock:configurationBlock];
}

+ (id)dataSourceWith2DArray:(NSArray *)array sectionIdentifiers:(NSArray *)cellIdentifiers configureCellBlock:(TableViewCellConfigureBlock)configurationBlock {
    return [[TwoDimensionalArrayDatasource alloc] initWith2DArray:array sectionIdentifiers:cellIdentifiers configureCellBlock:configurationBlock];
}

这些是类方法,因此调用alloc和init

是有效的

答案 1 :(得分:0)

你需要做的一件事就是在具体的子类中,不需要调用super init,因为你已经在调用alloc,它将进行内存分配。另外,在抽象类中,在调用具体类初始化方法之前,将self设置为nil,这样就不会有任何抽象类的痕迹。一旦你这样做,你就不需要删除过度骑行。