2

In regards to UITableView & UICollectionView & their respective protocols, UITableViewDataSource & UITableViewDelegate + UICollectionViewDelegate & UICollectionViewDataSource -- are there any pros and cons to implementing one method, but not the other or a particular set of methods and not the rest of the methods or a unique combination of specific methods?

For example, if I am to implement heightForFooter but not viewForFooter - what happens or can happen? Does this negative impact performance or the scroll of the table view?

Is there a guide which shows that which if any methods are implemented, others should be combined and dually implemented alongside them?

Alexander
  • 59,041
  • 12
  • 98
  • 151

1 Answers1

2

Re: correctness

Is there a guide which shows that which if any methods are implemented, others should be combined and dually implemented alongside them?

Not from what I've seen, though sometimes the documentation mentions it. E.g. from the docs of NSTableViewDataSource:

If you’re not using Cocoa bindings to provide data to the table view, the following methods are required:

  • numberOfRows(in:)
  • tableView(_:objectValueFor:row:)
  • tableView(_:setObjectValue:for:row:) (cell-based tables only)

In general, if a method is optional, but required from the context, then there will be a runtime error telling you to implment it, e.g.:

Illegal NSTableView data source (Foo). Must implement numberOfRowsInTableView: and tableView:objectValueForTableColumn:row:

Either that, or stuff will silently fail (e.g. if you don't implement NSTableViewDelegate.tableView(_:viewFor:row:), no drawing will happen, and all your cells will just be blank views.

Re: performance

There shouldn't be any real performance difference with not implementing optional methods.

Each of these methods is likely called as if you had this in Swift (most of these frameworks are still implemented in Objective C):

let result: Result? = yourTarget.someMethod?(someArg)

which is really just shorthand for:

let result: Result? = yourTarget.responds(to: #selector(YourTargetsClass.someMethod))
    ? target.method(someArg)
    : nil

That is, it's one dynamic method lookup to check if your object responds to the message, and one dynamic message send to actually invoke the method (for the case where it does respond).

There's a teeny tiny optimization that one could squeeze out here: if your method implementation is empty, then you're better off not having it at all. That will prevent a needless message send. Though it's obviously not something to worry about until you're sure it's a hotspot in a profiler.

Of course, nothing stops a library author from writing:

if yourObject.responds(to: #selector(someMessage)) {
    doSomethingVeryExpensiveForNoGoodReason()
}

... but that's unlikely.

Alexander
  • 59,041
  • 12
  • 98
  • 151
  • What are cocoa bindings? And thank you so much! –  May 27 '22 at 04:32
  • @ColinKyle did I mention cocoa bindings somewhere? I don’t see it – Alexander May 27 '22 at 14:06
  • "..If you’re not using Cocoa bindings to provide data to the table view, the following methods are required:" from the documents..." –  May 28 '22 at 08:55
  • Ah yes. They’re an implementation of pub/sub built on top of KVO. The big benefit was being able to click and drag your dataflows in interface builder, but for people who didn’t know about it, it felt like spooky action at a distance. It never made it to iOS, and is largely replaced by Combine. https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/WhatAreBindings.html – Alexander May 28 '22 at 13:41
  • What is a pub/sub? Also, KVO is a 'Key Value Observer', right? –  May 28 '22 at 15:34
  • @ColinKyle https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern and yes – Alexander May 28 '22 at 15:46