3

I am making a REALLY BASIC UITableView project without any data source. I am just displaying "1" on first and only cell.

I am returning 1 in both numberOfSectionsInTableView and numberOfRowsInSection. I am also doing an NSLog on both methods simply stating the name of the respective methods.

On initial load, I get this:

SomeShit[27511:936083] number of sections
SomeShit[27511:936083] number of rows in section
SomeShit[27511:936083] number of sections
SomeShit[27511:936083] number of rows in section
SomeShit[27511:936083] number of sections
SomeShit[27511:936083] number of rows in section

Why are these methods calling thrice? Correct me if I am wrong but this is really weird. I thought they were supposed to call only once because of number of items in both being just 1.

EDIT:

What I am doing in viewDidLoad,

self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
[self.view addSubview:self.tableView];

self.tableView.dataSource = self;
self.tableView.delegate = self;

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier];
esh
  • 2,842
  • 5
  • 23
  • 39
  • possible duplicate of http://stackoverflow.com/questions/2638359/uitableview-delegate-method-called-twice or http://stackoverflow.com/questions/7555039/why-numberofsectionsintableview-is-called-twice-in-uitableviewcontroller – Jakub Vano May 21 '15 at 10:47
  • I have looked at those. But 1) I don't set any tableFooterView or HeaderView, 2) I don't use IB. – esh May 21 '15 at 10:50
  • As mentioned in http://stackoverflow.com/questions/7555039/why-numberofsectionsintableview-is-called-twice-in-uitableviewcontroller, putting breakpoints in those methods and inspecting stack trace might shed some light on this. – Jakub Vano May 21 '15 at 10:52
  • Hmm sounds reasonable. I just did it. But it makes no sense. There was some method about loading a section and that's it. Never really points out to what could be the cause. – esh May 21 '15 at 10:59
  • @BlackFlam3 See my answer. You should not worry about the system implementation. – Léo Natan May 21 '15 at 11:02

3 Answers3

4

The delegate and data source are there to service the table view implementation, and methods may be called multiple times. You should not concern yourself with the implementation details of table views, just make sure your answers are consistent (i.e. you can answer correctly at any point in time and answers do not change without calling reloadData).

Léo Natan
  • 56,823
  • 9
  • 150
  • 195
  • Alright, I came to this after another problem which I have not put up just yet. Its about loading a section header and resizing it. Stuff was calling multiple times and I boiled it down to nothing but a tableview and 1 row. So you are sure it does not interfere with code that happens with these methods in future? – esh May 21 '15 at 11:02
  • These methods are normally short ones, so depending on how the table view caches results internally, it may ask your data source and delegate these questions several times. On the other hand, `cellForRowAtIndexPath` should not be called more than necessary, because that is a costly method. – Léo Natan May 21 '15 at 11:04
  • Yeah no, I am not calling `cellForRowAtIndexPath` any other time. – esh May 21 '15 at 11:06
4

Nowhere in the documentation does it say these methods are only call once in a reload data cycle.

You've made the assumption that they only need to be called once, but as you have shown, that's a bad assumption.

After reviewing the documentation for UITableView and UITableViewDataSource, the only promise is this.

-[UITableView numberOfSections]:

Discussion

UITableView gets the value returned by this method from its data source and caches it.

This means you can't know how calls to -[UITableView numberOfSections] will correspond with calls to -[UITableViewDataSource numberOfSectionsInTableView:].

Worse, the number of times these methods are called can (and have) change between different versions of iOS.


In short, make these methods idempotent and performant, and forget about implementation details of UITableView.

Community
  • 1
  • 1
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • "idempotent" is an interesting term which I was not aware of, and describes better what I meant by "consistent". – Léo Natan May 21 '15 at 12:32
3

You could try to figure out what is causing these reloads. Go to breakpoints section (1), press on "plus" button (2). Then add symbolic breakpoint with -[UITableView reloadData] in "symbol" field. enter image description here enter image description here

Then run your app and see the stack trace of method calls. You will be able to figure out the reason of such behaviour.

enter image description here

curious
  • 666
  • 4
  • 13