I have an iOS app that is built on a tabBarViewController
. The App utilizes Restkit
to pull data from a Restful web service which is persisted in CoreData
. In the event a user wants to logout of the app, I have a logout button that triggers a method to delete all objects in the CoreData entities. The main/home tab in the app is a UICollectionView
. The second tab has a UITableView
, and the last tab has a static table with two cells. One of the cells in the last tab allows the user to log out of the app.
By chance I noticed that when I logout, the numberOfSections
and numberOfRows
methods of the previous viewController I had open are getting triggered when I delete the entity that pertains to them. For example my collectionView
is populated with data persisted in the Gist
entity. If the user was viewing the collectionView
and navigated to the settings tab and chose to logout, my deleteAllEntitiesForName
method will then be called. When the method is told to delete the objects in the Gist
entity, for some reason the numberOfSections
and numberOfRows
methods are called in the viewController for the collectionView! The same will happen in the UITableViewController if that is where the user navigated from.
Why are methods from a totally separate view controller being hit when I am just clearing out data?
I am using NSLog
to be notified that these functions are getting triggered.
Even stranger, if I login and logout consecutively the methods will be called once for each time I have logged out. Here is the proof from my console....
First Logout after a build and run in the simulator:
2014-01-16 delete Gist
2014-01-16 Check numberOfSectionsInCollectionView
2014-01-16 Check numberofItemsInSection
2014-01-16 delete ActivityData
2014-01-16 delete FollowActivityData
2014-01-16 delete InsertNodes
Login and log back out while still running the app in the simulator:
2014-01-16 delete Gist
2014-01-16 Check numberOfSectionsInCollectionView
2014-01-16 Check numberofItemsInSection
2014-01-16 Check numberOfSectionsInCollectionView
2014-01-16 Check numberofItemsInSection
2014-01-16 delete ActivityData
2014-01-16 delete FollowActivityData
2014-01-16 delete InsertNodes
Here is the method I am using to clear the data persisted in the entities.
- (void) deleteAllEntitiesForName:(NSString*)entityName {
NSEntityDescription *entityDescription = [NSEntityDescription entityForName: entityName inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
NSError *error = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
if (array != nil) {
for(NSManagedObject *managedObject in array) {
[managedObjectContext deleteObject:managedObject];
}
error = nil;
[managedObjectContext save:&error];
}
}
I can't say that I notice any problems with the way the app runs. I've confirmed that all the data is cleared from the core data entities. But I am concerned that I may be doing something wrong here. The especially concerning part is that the methods are triggered once for every time the user has logged out.
Does anyone have any idea what is going on here? Should I be concerned? How do I handle this? Thanks for the input!
I believe I got the deleteAllEntitiesForName
method from here Delete/Reset all entries in Core Data?
===========UPDATE============
The collectionView and tableView are populated using a FetchedResultsController. Here is my implementation along with commentary of some of some of my findings.
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
NSLog(@"CHECK didChangeObject");
//THIS METHOD IS TRIGGERED FIRST AFTER THE DELETE HAS STARTED.
//IT IS TRIGGERED ONCE FOR EVERY CELL IN THE COLLECTION OR ONCE FOR EVERY ROW IN THE TABLE
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
NSLog(@"CHECK didChangeContent");
//THIS METHOD IS TRIGGERED NEXT. IT IS TRIGGERED ONCE AFTER ALL THE OBJECT DATA WAS DELETED IN THE METHOD ABOVE.
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
NSLog(@"Check numberOfSectionsInCollectionView");
return [[self.fetchedResultsController sections] count];
//THIS METHOD IS THEN TRIGGERED FOLLOWED BY THE FETCHED RESULTS CONTROLLER
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
NSLog(@"Check numberofItemsInSection");
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
//FOLLOWING THE FRC THIS METHOD IS CALLED AND ONCE AGAIN THE FRC IS TRIGGERED
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
//THIS IS WHERE GUTS OF THE CELLS ARE POPULATED. I LEFT IT OUT FOR BREVITY.
//THIS METHOD IS NEVER TRIGGERED WHEN CLEARING OUT THE CORE DATA.
}