1

I'm working on an app using Stanford's CoreDataTableViewController. All database saving and fetching was working correctly until I removed the CDTVC files and then added them again. Now it's not fetching anything. CellForRowAtIndexPath is not being called and although the fetch request returns the correct number of entries in the database (reflecting each new entry), the numberOfRowsInSection and numberOfSections both return 0.

I have no idea what could have happened. I tried recreating the subclass, creating a completely new Table View Controller, I deleted the app from the simulator and from my device. My outlets as dataSource and delegate are set, the fetchedResultsController gets set and is not nil and the methods inside CoreDataTableViewController, setFetchedResultsController and performFetch, are still being called.

Thanks

kanstraktar
  • 5,357
  • 2
  • 21
  • 29
  • Have you checked the return values of `numberOfSectionsInTableView` and `numberOfRowsInSection`? – Timothy Moose Aug 26 '13 at 14:16
  • both of them return 0. I had already corrected numberOfSectionsInTableView to return 1, but how can I match again the number of rows with what I fetch. I tried to return a random number (smaller than what i have in my databes) and it crashes – kanstraktar Aug 26 '13 at 14:51
  • I'm confused by your question. `CoreDataTableViewController` provides an implementation of `numberOfRowsInSection` that get the result from the fetchedResultsController. If it is returning zero, then it is likely you're either not executing the fetch or the fetch is returning zero results. If the fetch is returning zero results, then you've probably either got an incorrect fetch request or no data in your database. – Timothy Moose Aug 26 '13 at 14:57
  • that's why i'm also confused. the database is populated, the fetch request is executed correctly, the same code that worked perfectly just stopped working after I removed and reinserted the same two files with the CDTVC... – kanstraktar Aug 26 '13 at 15:11
  • By "the fetch request is executed correctly" are you saying you've verified it's returning non-zero number of results? – Timothy Moose Aug 26 '13 at 15:18
  • yes, and each time i add something new it reflects on the next fetch. in CDTVC though numberOfSections is 0. if i manually set this to 1, then numberOfRows is 0 – kanstraktar Aug 26 '13 at 15:34
  • Sounds to me like you failed to set the `fetchedResultsController` property of your view controller. – Timothy Moose Aug 26 '13 at 15:37
  • it's not nil and the methods in CDTVC setFetchedResultsController and performFetch get called and executed – kanstraktar Aug 26 '13 at 15:42

2 Answers2

1

final answer

Updating my answer after chat session. Switching to TLIndexPathTools's TLIndexPathController instead of NSFetchedResultsController resolved the issue.

answer #2

It sounds like you're saying the following method is returning zero:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}

And that you've verified the fetchedResultsController is set and that you've called performFetch and that the results are non-zero, i.e. the fetchedObjects property is returning a non-empty array. I don't see how all of those things can be true and have the above method return 0. Can you put a breakpoint in the above method and re-verify these things? Perhaps this method is getting called before you call performFetch.

If you continue to be stuck, you could try my TLIndexPathTools library. It provides an alternative to NSFetchedResultsController. Check out the Core Data sample project.

answer #1

Check that you're setting the fetchedResultsController property of your table view controller. From the description of your problem, it sounds like this property is nil.

Timothy Moose
  • 9,895
  • 3
  • 33
  • 44
  • it's not nil, the methods in CDTVC setFetchedResultsController and performFetch get called and executed and the fetchedResultsController comes back not nil – kanstraktar Aug 26 '13 at 15:45
  • OK, first of all thank you for all your answers and patience. I've created a new subclass meanwhile, with only the basic code for setting the fetchedResultsController and it did nothing. But then, following your answer, I logged the [fetchedObjects count] and this - naming this property - somehow did it. It showed the same number as my other log for the fetch showed, but also displayed everything back in the table view. It's miraculously weird and I still don't know what happened. I will mark this as the correct answer, for all your help and because it somehow unblocked the code. Thanks again – kanstraktar Aug 26 '13 at 16:43
  • it's doing the same thing, sorry... and this time it really went from working to running it again and not working. the order in which it goes through the methods inside CDTVC is: setFetchedResultsController, followed by performFetch, it goes 3 times in numberOfSectionsInTableView (here fetchedResultsController is not nil, but [fetchedObjects count] is 0) and then it's on screen, showing nothing. the logs i have in my subclass show that the fetch is not returning nil. – kanstraktar Aug 27 '13 at 10:30
  • I opened a chat room if you want to [talk through it](http://chat.stackoverflow.com/rooms/info/36331/moose01?tab=general). – Timothy Moose Aug 27 '13 at 14:01
  • Got it to work with the recommended TLIndexPathTools library download and an excellent walk through by Timothy. Great and useful library and equally a support. Thank you for everything. – kanstraktar Aug 27 '13 at 16:25
0

If tableView:cellForRowAtIndexPath: is not being called there is three possible solutions :

  • the tableview dataSource property is not set up properly ;
  • or numberOfSectionsInTableView: is returning 0 ;
  • or finally tableView:numberOfRowsInSection: is returning 0.

My guess, I would go for the third one from what you've told us.

And usually, with a fetched results controller you would use something close to that :

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return _fetchedResultsController.sections.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSUInteger rows = 0;
    id sectionInfo = [_fetchedResultsController.sections objectAtIndex:section];
    rows = [sectionInfo numberOfObjects];
    return rows;
}
dulaccc
  • 1,148
  • 11
  • 12
  • you're right, I checked for section 0 and indeed it returns 0. how would I set this to match what I fetch with the fetchedResultsController or what should I do in order for this tableViewController to work as it did before? thanks again – kanstraktar Aug 26 '13 at 14:45
  • I've edited my answer to show the usual practice associated with a fetched results controller. hope it helps – dulaccc Aug 26 '13 at 19:23