Ios 理解代理与块。(重构代码以使用委派而不是块)

Ios 理解代理与块。(重构代码以使用委派而不是块),ios,objective-c,uitableview,delegates,objective-c-blocks,Ios,Objective C,Uitableview,Delegates,Objective C Blocks,我在网上找到了一个例子,说明了如何分离UITableview的数据源,从而使代码更加可重用。但是,在这段代码中,它使用块而不是委托来更新单元格。到目前为止,在我的项目中,我一直在使用委托,因此为了保持一致性,我希望它保持这种方式,以便有人能够解释更好的块,并帮助我重构下面的示例代码,以包含委托,而不是块。我使用的例子来自 它在UIViewController中的用法是: void (^configureCell)(PhotoCell*, Photo*) = ^(PhotoCell* cell,

我在网上找到了一个例子,说明了如何分离UITableview的数据源,从而使代码更加可重用。但是,在这段代码中,它使用块而不是委托来更新单元格。到目前为止,在我的项目中,我一直在使用委托,因此为了保持一致性,我希望它保持这种方式,以便有人能够解释更好的块,并帮助我重构下面的示例代码,以包含
委托
,而不是块。我使用的例子来自

它在
UIViewController
中的用法是:

void (^configureCell)(PhotoCell*, Photo*) = ^(PhotoCell* cell, Photo* photo) {
cell.label.text = photo.name;
};
photosArrayDataSource = [[ArrayDataSource alloc] initWithItems:photos
                                            cellIdentifier:PhotoCellIdentifier
                                        configureCellBlock:configureCell];
self.tableView.dataSource = photosArrayDataSource;
我每天都努力学习新的东西,如果有人能帮助我,那就太好了。作为一名开发人员,我希望每天都能有所提高:)


我理解数据源的分离,但是使用块而不是委托对我来说是新的(奇怪的)。

事实上,在您的示例中,ArrayDataSource类是一个“通用”类,用于所有UITableView的数据源

如果仔细观察ArrayDataSource(ArrayDataSource.m)的实现,您会发现它调用了UITableViewDatasource的经典方法(
numberOfRowsInSection:
cellForRowAtIndexPath:
…)。但是,当泛型类必须为特定的indexPath配置单元格内容时,它不知道如何处理
id项
,因此它调用特定块(使用
self.configureCellBlock(cell,item);
)从泛型类外部化此行为

块的概念类似于函数指针,您只需告诉泛型ArrayDatasource类,当它必须在行
self.configureCellBlock(cell,item)上配置单元格内容时,要调用什么函数。在您的情况下,单元格将显示照片的名称(
cell.label.text=photo.name;

因此,在本例中,您仍然在
ArrayDatasource
类中使用UITableView的数据源概念,并且您可以将默认的
UITableViewDatasource
的所有需要放在
ArrayDatasource.m
中(例如实现
HeightforRowatineXpath:
等等…),防止对所有tableView的数据源进行复制粘贴(如果您的应用程序有许多
UITableView
)。 这里块的目的不是取代数据源概念,而是告诉泛型类做什么的更方便的方法


我希望我很清楚,但解释这些概念并不总是那么容易的!:)

非常感谢这非常有帮助。:)
//
//  ArrayDataSource.h
//  objc.io example project (issue #1)
//

#import "ArrayDataSource.h"


@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
void (^configureCell)(PhotoCell*, Photo*) = ^(PhotoCell* cell, Photo* photo) {
cell.label.text = photo.name;
};
photosArrayDataSource = [[ArrayDataSource alloc] initWithItems:photos
                                            cellIdentifier:PhotoCellIdentifier
                                        configureCellBlock:configureCell];
self.tableView.dataSource = photosArrayDataSource;