   // recurse. Configure the cell and send back the height of the compressed
   // fitting size. This relies on an explicit preferred width and constraints
   // properly set up. If there are no constraints, use the cell's frame height.
-  public override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+  open override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
     let cellIdentifier = dataSource.cellIdentifier(forRow: indexPath)
     guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) else {
       return super.tableView(tableView, heightForRowAt: indexPath)

  /// set up. Uses user-defined run-time attributes to derive the entity
  /// description and sort descriptor, and optionally also the section name
  /// key-path and cache name.
  public var fetchedResultsController: NSFetchedResultsController<Result> {
    if dataSource.fetchedResultsController == nil {
      dataSource.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
                                                                       managedObjectContext: managedObjectContext,

  // assumes that you have already set up the cell-identifier-for-row and
  // configure-cell-for-object blocks, or will do so soon before the table view
  // starts to load.
  open override func viewDidLoad() {
    super.viewDidLoad()
    if tableView.dataSource == nil {
      tableView.dataSource = dataSource
