驯服iOS中的大量控制器第3部分

欢迎来到“ 驯服iOS中的大量控制器 ”的最后一部分。 强烈建议您先阅读本系列的第1部分和第2部分,然后再继续本文。

在前面的文章中,我们将UITableView控件的数据源提取到了一个单独的类“ ShoppingListDataSource ”中。 这将所有数据源功能从ShoppingListViewController移到了数据源的指定类中。 这项技术极大地帮助我们减小了控制器的尺寸,并将其放置在正确的位置。

当用户选择购物清单时,他/她被发送到杂货项目屏幕,在该屏幕上显示所选购物清单的所有相关项目。 这意味着我们需要为杂货项目创建一个单独的数据源。 GroceryItemsDataSource看起来与ShoppingListDataSource完全一样,唯一的区别是GroceryItemsDataSource将处理GroceryItem类型的商品,而不是ShoppingList,如下面的屏幕快照所示:

一种替代方法是创建适用于所有类的通用数据源和数据管理器类。

通用的UITableViewDataSource和数据管理器:

通用的TableViewDataSource将独立于类实体,单元格或与对象关联的数据管理器/数据提供程序的类型。 UITableViewDataSource的声明如下所示:

  class TableViewDataSource :NSObject,UITableViewDataSource,FetchedResultsDataProviderDelegate { 

如您所见,TableViewDataSource是一个通用类,您可以在其中传递单元格和实体的类型。 由于我们正在使用CoreData,因此我们的实体类继承自自定义协议ManagedObjectType,这是我们的自定义类型。 TableViewDataSource初始化程序采用所有必需的参数,如下所示:

  init(cellIdentifier:String,tableView:UITableView,dataProvider:FetchedResultsDataProvider ,cellConfigurationHandler:(CellType,Entity)->()){ 
  self.cellIdentifier = cellIdentifier 
  self.cellConfigurationHandler = cellConfigurationHandler 
  self.dataProvider = dataProvider 
  self.tableView = tableView 
  super.init() 
  } 

需要注意的一件事是dataProvider参数,它也是FetchedResultsDataProvider的通用类型。 让我们检查ShoppingListTableViewController中的代码,该代码声明了数据源和数据提供程序。

 私有var dataSource:TableViewDataSource ! 
 私人var dataProvider:FetchedResultsDataProvider ! 

接下来,我们将使用适当的信息初始化dataSource和dataProvider属性。

 覆盖func viewDidLoad(){ 
  super.viewDidLoad() 
  self.dataProvider = FetchedResultsDataProvider(managedObjectContext:self.managedObjectContext) 
  self.dataSource = TableViewDataSource(cellIdentifier:“ ShoppingListTableViewCell”,tableView:self.tableView,dataProvider:self.dataProvider,cellConfigurationHandler:{(cell:UITableViewCell,shoppingList:ShoppingList)在 
  cell.textLabel?.text = shoppingList.title 
  }) 
  self.tableView.dataSource = self.dataSource 
  } 

其他一切都保持不变! 我们刚刚用通用实现替换了ShoppingList的具体实现。 这意味着我们现在不必为GroceryItemsDataSource和GroceryItemsDataManager创建单独的实现。

在这一点上,您必须考虑通用的实现是最好的方法,它将解决您的所有问题。 不幸的是,没有灵丹妙药。 如果您选择通用数据源和数据提供程序,则肯定会少得多的代码,但这要付出一定的代价。 成本是编写通用实现时获得的灵活性。 泛型意味着..泛型! 这意味着您的实现适用于多个类。 如果参与的类稍有差异,则您的通用实现需要进行更新以适应这些更改。

我们已经到了系列的结尾。 我真的很喜欢编写本系列文章,并希望它能帮助您编写更干净,更好的代码。 我将在本文结尾为读者提供一个问题,如下所述。

在编写单独的数据源和数据提供程序时,您将选择哪种方式?为什么?

[下载项目]