Saturday, July 08, 2017

Type Erasure

Say that I have a view model that has a reference to a data source object generated by another object like a factory. In my view model I would have a property that is typed as AnyDataSource. I also have a property that is of type FRCDataSource, this is the object that will be wrapped in the AnyDataSource object.

class AddToDoViewModel {
    var dataSource : AnyDataSource<Item>!
    var frcDataSource : FRCDataSource<Item>!

FRCDataSource is defined as :

class FRCDataSource<T: NSManagedObject> : DataSourceProtocol {

    var fetchedResultsController : NSFetchedResultsController<T>!

    init(fetchedResultsController: NSFetchedResultsController<T>) {
    self.fetchedResultsController = fetchedResultsController

The FRCDataSource class is a wrapper around an NSFetchedResultsController type. The generic type constraint on FRCDataSource limits the type of T to be an object that derives from NSManagedObject. Also note that FRCDataSource is specialized by the same type as NSFetchedResultsController. To create an FRCDataSource we do the following in reloadData()

func reloadData() {
    self.frcDataSource = FRCDataSource(fetchedResultsController:self.fetchedResultsController)

We create an FRCDataSource, passing in the NSFetchedResultsController class property. Now our frcDataSource property is set to a FRCDataSource instance that internally stores a NSFetchedResultsController instance. In this case, I am creating an instance of FRCDataSource directly, although I could easily delegate this responsibility to another object which would create and return an FRCDataSource.

Once I’ve created an FRCDataSource object from the NSFetchedResultsController, I can now add a method that will create an AnyDataSource derived object and store it in the dataSource property of the view model:

func createDataSource<T: DataSourceProtocol>(dataSource: T) where T.DataSourceItem == Item 
    self.dataSource = AnyDataSource(dataSource)

The createDataSource() takes an object that adopts the DataSourceProtocol, creates an AnyDataSource object and sets the dataSource property. There are a few things to take note of here:

Once the data source is created we will have an AnyDataSource typed object that can be used in place of a DataSourceProtocol type.

Basically what we’ve done is create wrappers for two types

This page is powered by Blogger. Isn't yours?