I read quite a few questions and answers no this problem. Some are for Ojective C. Some are for iOS. The ones that were close to what I need didn't work.
I've set up a protocol for delegation. It doesn't work. The problem is that delegate variable isn't set. I need the reference to an active controller.
Delegator
protocol SwitchTabDelegate: class {
  func selectTab(tab: Int)
}
class ViewController: NSViewController {
  weak var delegate: SwitchTabDelegate?
  override func viewDidLoad() {
    super.viewDidLoad()
  }
  @IBAction func selectCompositions(_ sender: NSButton) {
    if let delegate = self.delegate {
      delegate.selectTab(tab: 2)
    }
    else {
      print("self.delegate is nil")
    }
    print("delegate called")
  }
}
Delegatee
class TabViewController: NSTabViewController, SwitchTabDelegate {
  var viewController : ViewController?;
  override func viewDidLoad() {
    super.viewDidLoad()
    //viewController = storyboard?.instantiateController(withIdentifier: "viewController") as? ViewController
   // viewController?.delegate = self
  // print(viewController)
  }
  func selectTab(tab: Int) {
    print("In the delegate")
    switchToDataTab()
  }
  func switchToDataTab() {
    Timer.scheduledTimer(timeInterval: 0.2, target: self,
        selector: #selector(switchToDataTabCont),
        userInfo: nil, repeats: false)
  }
  func switchToDataTabCont(){
    self.selectedTabViewItemIndex = 2
  }
}
The delegatee is the main NSViewContoller. On the storyboard, it contains two buttons and a Container view controller. Embedded in the container view controller is the TabViewController, the delegatee. You can see in the delegatee where I tried to get a reference. It does get a reference, presumably to the newly instantiated instance. I need a reference to the original view controller that was spun up when the application started.
Answer
I added the following code to the delegator:
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
  let controller = segue.destinationController as! TabViewController
  self.delegate = controller as SwitchTabDelegate
 }
That's not how it should work following the design pattern. The delegator should have no knowledge of the delegatee. I've spent way too much time on this issue so a hack is going to do.
                        
When using storyboards, you want to "push" references to children when they are created vs. pulling them from an upstream controller. This is what -prepareForSegue:sender: is used for.