0

Edit: someone suggested this was a duplicate of another question. It is not I have implemented:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section //(in swift of course).

In a ViewController I programmatically create a tableView and add it as a subview. I have a class named DataSource that adopts UITableViewDelegate and UITableViewDataSource via two extensions.

I'm following an example given here

I'm getting an error:

ViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7f88cc406ac0'

0x7f88cc406ac0 is the address of the containing ViewController.

Even if I make the containing ViewController adopt UITableViewDelegate via an extension and then that calls the DataSource implementation of tableView:numberOfRowsInSection I still see the error.

Ideas?

import UIKit

class GenericDataSource: NSObject {
    let identifier     = "cell"
    var array: [Any]   = ["Dogs","Cats","Mice"]

    func registerCells(forTableView tableView: UITableView) {
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: identifier)
//        tableView.register(UINib(nibName: "", bundle: nil), forCellReuseIdentifier: identifier)
    }

    func loadCell(atIndexPath indexPath: IndexPath, forTableView tableView: UITableView) -> UITableViewCell {
//        let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath)

        let cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell")
        cell.textLabel!.text = array [indexPath.row] as? String
        return cell
    }
}

// UITableViewDataSource
extension GenericDataSource: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 0
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return array.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return self.loadCell(atIndexPath: indexPath, forTableView: tableView)
    }

}
// UITableViewDelegate
extension GenericDataSource: UITableViewDelegate {

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)      {

    }
}
protocol GenericDataSourceDelegate: class {
    // Delegate callbacks methods
}

extension ViewController: UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return self.dataSource.numberOfSections(in: tableView)
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.tableView(tableView,numberOfRowsInSection:section)
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return dataSource.tableView(tableView,cellForRowAt:indexPath)
    }
}

func requestTableView() -> UITableView {
    return UITableView(frame: UIScreen.main.bounds, style: UITableViewStyle.plain)
}

class ViewController: UIViewController {
    var tableView: UITableView?
    var dataSource = GenericDataSource()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView = requestTableView()

        if(tableView != nil) {
            self.tableView!.delegate      =   self
            self.tableView!.dataSource    =   dataSource
            self.view.addSubview(self.tableView!)
        }
    }
}

As requested here is the entire error message:

2018-03-09 08:37:52.479763-0800 Job[3560:6187366] -[Job.ViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7f9164c065b0 2018-03-09 08:37:52.623521-0800 Job[3560:6187366] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Job.ViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7f9164c065b0' * First throw call stack: ( 0 CoreFoundation 0x00000001089fc12b exceptionPreprocess + 171 1 libobjc.A.dylib 0x0000000104d08f41 objc_exception_throw + 48 2 CoreFoundation 0x0000000108a7d024 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132 3 UIKit 0x00000001057d8f51 -[UIResponder doesNotRecognizeSelector:] + 295 4 CoreFoundation 0x000000010897ef78 ___forwarding_ + 1432 5 CoreFoundation 0x000000010897e958 _CF_forwarding_prep_0 + 120 6 UIKit 0x0000000105713b4c -[UITableView _numberOfRowsInSection:] + 62 7 UIKit 0x00000001059c60e1 -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 2389 8 UIKit 0x00000001059cc5ab -[UITableViewRowData rectForFooterInSection:heightCanBeGuessed:] + 487 9 UIKit 0x00000001059cc711 -[UITableViewRowData heightForTable] + 61 10 UIKit 0x00000001056c1a65 -[UITableView _updateContentSize] + 372 11 UIKit 0x00000001056f267d -[UITableView _rebuildGeometry] + 66 12 UIKit 0x00000001056f003c -[UITableView didMoveToWindow] + 145 13 UIKit 0x000000010566d147 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1748 14 UIKit 0x0000000105686a81 -[UIScrollView _didMoveFromWindow:toWindow:] + 84 15 UIKit 0x000000010565f1e1 45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 151 16 UIKit 0x000000010565f0c8 -[UIView(Hierarchy) _postMovedFromSuperview:] + 828 17 UIKit 0x000000010566fcbd -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1973 18 UIKit 0x0000000105618aa2 -[UIWindow addRootViewControllerViewIfPossible] + 845 19 UIKit 0x0000000105618ed7 -[UIWindow _setHidden:forced:] + 294 20 UIKit 0x000000010562be54 -[UIWindow makeKeyAndVisible] + 42 21 UIKit 0x000000010559e8b8 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4737 22 UIKit 0x00000001055a3aeb -[UIApplication _runWithMainScene:transitionContext:completion:] + 1720 23 UIKit 0x000000010596d6f8 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke + 924 24 UIKit 0x0000000105d434c8 +[_UICanvas _enqueuePostSettingUpdateTransactionBlock:] + 153 25 UIKit 0x000000010596d2f1 -[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:] + 249 26 UIKit 0x000000010596db6b -[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:] + 696 27 UIKit 0x00000001062eba69 __82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke + 262 28 UIKit 0x00000001062eb922 -[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:] + 444 29 UIKit 0x0000000105fc89c8 __125-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke + 221 30 UIKit 0x00000001061c7b06 _performActionsWithDelayForTransitionContext + 100 31 UIKit 0x0000000105fc888b -[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:] + 231 32 UIKit 0x0000000105d42b25 -[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:] + 392 33 UIKit 0x00000001055a236a -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 523 34 UIKit 0x0000000105b7d605 -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 369 35 FrontBoardServices 0x000000010a8bfcc0 -[FBSSceneImpl _didCreateWithTransitionContext:completion:] + 338 36 FrontBoardServices 0x000000010a8c87b5 __56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2 + 235 37 libdispatch.dylib 0x0000000109b1e33d _dispatch_client_callout + 8 38 libdispatch.dylib 0x0000000109b239f3 _dispatch_block_invoke_direct + 592 39 FrontBoardServices 0x000000010a8f4498 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK + 24 40 FrontBoardServices 0x000000010a8f414e -[FBSSerialQueue _performNext] + 464 41 FrontBoardServices 0x000000010a8f46bd -[FBSSerialQueue _performNextFromRunLoopSource] + 45 42 CoreFoundation 0x000000010899f101 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 43 CoreFoundation 0x0000000108a3ef71 __CFRunLoopDoSource0 + 81 44 CoreFoundation 0x0000000108983a19 __CFRunLoopDoSources0 + 185 45 CoreFoundation 0x0000000108982fff __CFRunLoopRun + 1279 46 CoreFoundation 0x0000000108982889 CFRunLoopRunSpecific + 409 47 GraphicsServices 0x000000010b1889c6 GSEventRunModal + 62 48 UIKit 0x00000001055a55d6 UIApplicationMain + 159 49 Jobr 0x00000001043ee5e7 main + 55 50 libdyld.dylib 0x0000000109b9ad81 start + 1 51 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

bhartsb
  • 1,316
  • 14
  • 39
  • Please update your question with *your* relevant code. Point out the exact line causing the error. – rmaddy Mar 08 '18 at 01:43
  • @maddy I had put in the link to the sample code I used but I've now added my exact code. – bhartsb Mar 08 '18 at 01:49
  • Use a breakpoint and check if the delegate and dataSource settings are being called(`if (tableView != nil) {`) – Xcoder Mar 08 '18 at 02:48
  • @Xcoder Yes I checked that already. They are being set. – bhartsb Mar 08 '18 at 03:42
  • Possible duplicate of [tableView:numberOfRowsInSection:\]: unrecognized selector sent to instance](https://stackoverflow.com/questions/12431013/tableviewnumberofrowsinsection-unrecognized-selector-sent-to-instance) – Cristik Mar 08 '18 at 07:19
  • @Cristik It is not a duplicate I have implemented the method - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section //(in swift of course). – bhartsb Mar 08 '18 at 10:11
  • In the duplicate, the OP provides the whole error message(with the "reason:"). Do you mind doing so? – Xcoder Mar 08 '18 at 21:54
  • @Xcoder I've added the whole error message. – bhartsb Mar 09 '18 at 16:43
  • @bhartsb Let me know if my answer worked for you :) – Xcoder Nov 26 '18 at 01:14

1 Answers1

0

In the Apple Documentation, the tableView numberOfRowsInSection method is a data source method, not a delegate method.

Therefore, you need to create a new extension and move the numberOfRowsInSection method inside of it:

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.tableView(tableView,numberOfRowsInSection:section)
    }
} 
Xcoder
  • 1,433
  • 3
  • 17
  • 37