This is a really great question.
We can break this into two reasons - a general one and a specific one that is a common example of it.
First, though, notice that it's even more than that. A UITableView
can have two delegate controller objects, a UITableViewDataSourceDelegate
and a UITableViewDelegate
. The first provides the data; the second responds to actions taken on the displayed data. Why all these layers of abstraction? Why not just stick it in the UIViewController
?
The general reason not to is suggested by the name 'UIViewController
'. It's meant to control views. In iOS and I expect in android-land, there is a strong temptation to just 'stick it in the view controller' - leading to the Very Large View Controller antipattern, which you can read about a lot (eg here).
Far better for maintenance and organization for the view controller to lay out views and handle button presses, and some other controller object to handle the well-defined and really quite separate responsibility of providing the data.
It's not uncommon to have some sort of object that handles the data anyway - a shopping cart, or list of real estate properties, etc - that encapsulates additional business logic (providing subtotals, for example) but fundamentally already 'has' the data. In that case, provide a category or a lightweight controller that can 'bridge' between that data and the table view, and pass the model object, instead of an array, between view controllers.
This gets into the specific: in iOS, we have things like NSFetchedResultsController
. This is a fantastic class that does a tremendous amount of data sorting, pagination, addition, deletion, slicing, dicing, folding, spindling, and mutilating for you - and it also speaks UITableView
's language natively. Pass one of those around and you keep your view controllers clean and tidy and separate from your data.