title: swift tableView in custom view programatically - losing reference to controllers delegate and data source
body: <p>I am trying to learn MVVM pattern and writing all my views programatically using Snapkit. I am creating hamburger menu which consist of simple tableView and I have a problem, that my tableView in cusom view is losing delegate and data source references on the view controller. I also tried using UITableViewController, but result is the same, here is my code:</p>
  
  <p><strong>ViewModel:</strong></p>
  
  <pre><code>class SideMenuViewModel {
  
      let cellId = "SideMenuCellId"
      weak var delegate: SideMenuViewModelDelegate?
      private let cells: [SideMenuItemStruct] = [SideMenuItemStruct(type: .allDogs, title: "ALL DOGOS"),
                                             SideMenuItemStruct(type: .randomDog, title: "RANDOM DOGO")]
  
      init(delegate: SideMenuViewModelDelegate) {
          self.delegate = delegate
      }
  
      var numberOfRows: Int {
          return cells.count
      }
  
      func selectedMenuItem(indexPath: IndexPath) {
          switch SideMenuItemsEnum(rawValue: indexPath.row) {
          case .allDogs?:
              delegate?.selectedMenuItem(selectedItem:        SideMenuItemsEnum.allDogs)
          case .randomDog?:
              delegate?.selectedMenuItem(selectedItem: SideMenuItemsEnum.randomDog)
          default:
              print("error when choosing menu item")
          }
      }
  
      func cellForRow(_ tableView: UITableView, indexPath: IndexPath) -&gt; UITableViewCell {
          guard let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? SideMenuCell else {
              fatalError("could not deque Side menu cell")
          }
  
          cell.selectionStyle = .none
          cell.setUpCell(sideMenuItem: cells[indexPath.row])
          return cell
          }
  }
  </code></pre>
  
  <p><strong>View:</strong></p>
  
  <pre><code>class SideMenuView: UIView {
  
      var sideMenuTableView = UITableView()
  
      let sideMenuButton = UIButton(type: .system)
  
      weak var delegate: UITableViewDelegate? {
          get {
              return sideMenuTableView.delegate
          }
          set {
              sideMenuTableView.delegate = newValue
          }
      }
  
      weak var dataSource: UITableViewDataSource? {
          get {
              return sideMenuTableView.dataSource
          }
          set {
              sideMenuTableView.dataSource = newValue
          }
      }
  
      override init(frame: CGRect) {
          super.init(frame: frame)
          initUI()
      }
  
      required init?(coder aDecoder: NSCoder) {
          fatalError("init(coder:) has not been implemented")
      }
  
      override func awakeFromNib() {
          super.awakeFromNib()
      }
  
      private func initUI() {
          addSubview(sideMenuButton)
          addSubview(sideMenuTableView)
  
          setUpSideMenuButton()
          setUpSideMenuTableView()
      }
  
      private func setUpSideMenuButton() {
          sideMenuButton.setTitle("DELEGATE", for: .normal)
          sideMenuButton.addTarget(self, action: #selector(buttonPrint), for: .touchUpInside)
          sideMenuButton.snp.makeConstraints { (make) in
              make.top.equalTo(self)
              make.centerX.equalTo(self)
          }
      }
  
      @objc func buttonPrint() {
          print("delegate: \(String(describing: sideMenuTableView.delegate)), data source: \(String(describing: sideMenuTableView.dataSource))")
      }
  
      private func setUpSideMenuTableView() {
          sideMenuTableView.snp.makeConstraints { (make) in
              make.top.equalTo(sideMenuButton.snp.bottom)
              make.bottom.equalTo(self)
              make.left.equalTo(self)
              make.right.equalTo(self)
          }
      }
  
  }
  </code></pre>
  
  <p><strong>And my View Controller:</strong></p>
  
  <pre><code>class SideMenuController: UIViewController {
  
      fileprivate let viewModel: SideMenuViewModel
  
      fileprivate var sideMenuView: SideMenuView {
          return view as! SideMenuView
      }
  
      init(viewModel: SideMenuViewModel) {
          self.viewModel = viewModel
          super.init(nibName: nil, bundle: nil)
      }
  
      override func loadView() {
          let sideMenuView = SideMenuView()
          sideMenuView.sideMenuTableView.delegate = self
          sideMenuView.sideMenuTableView.dataSource = self
          view = sideMenuView
      }
  
      override func viewDidLoad() {
          super.viewDidLoad()
          sideMenuView.sideMenuTableView.register(SideMenuCell.self, forCellReuseIdentifier: viewModel.cellId)
      }
  
      required init?(coder aDecoder: NSCoder) {
          fatalError("init(coder:) has not been implemented")
      }
  
  }
  
  extension SideMenuController: UITableViewDelegate, UITableViewDataSource {
  
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
          return viewModel.numberOfRows
      }
  
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
          return viewModel.cellForRow(tableView, indexPath: indexPath)
      }
  
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          viewModel.selectedMenuItem(indexPath: indexPath)
          print("awd")
      }
  
  }
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/RHNn6.png" rel="nofollow noreferrer">Simulater after init</a></p>
  
  <p><a href="https://i.stack.imgur.com/BqBou.png" rel="nofollow noreferrer">Simulator after scroll</a></p>
  
  <p><a href="https://i.stack.imgur.com/ECQ1u.png" rel="nofollow noreferrer">DELEGATE button tapped result</a></p>
  
  <p>I am learning from few tutorials and they didn't had this problem, but they were all using Interface builders, which I want to avoid. Please, let me know, if I am doing something really wrong, thanks.</p>
  
  <p><strong>SOLUTION</strong></p>
  
  <p>I found out, I made a really huge mistake outside of this showed code, I initialized SideMenuController in a function and didn't keep reference to it, so naturaly it was automaticly deinitialized after end of a function. It was a really bad mistake. Thanks for all answers, code here is working, but I refactored it according to answer.</p>