繁体   English   中英

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

[英]Creating a class cluster in objective c - methods called on abstract super class?

我正在尝试为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时,为什么这些消息会转到抽象类?

UPDATE

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

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

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

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

我建议你在“抽象类”中使用工厂模式 -

@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是有效的

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM