Handling and accessing view controllers in nav controllers throughout app's lifespan
Hi there,
I have a Navigation Controller with a Table View Controller as it's root. This table view lists some data from a database which is stored in an array. This array is a property of the Table View Controller. When a row is selected, this the row id is passed to a View Controller (that is pushed onto the Nav Controllers stack) that handle's the full editing of that record. On load, it pulls in all the remaining data to do with that record (that is not needed by the Table View for just displaying cells).
Once the row is edited, and the user presses a button, I want to be able to somehow get the previous navigation controller and tell it to update it's records and call the reloadData method on the Table View.
My question is how can you access previous View Controllers? Should you create "global" pointers (say in the app delegate) to all the main View Controllers in your app? As these views are always retained during the app's lifespan by the main navigation controller, is this such a bad thing to do? This way you can always refer to a particular controller and tell it to update?
I guess this is a general question about how to structure all the View Controllers in apps. Whether you just alloc+init them, add them to the Navigation Controller and release them, or whether you always keep pointers to them so you can fully control them from anywhere during the apps lifespan.
Do you really need to do this updating from the 2nd level view controller? Or do you just need to make sure the main view controller updates itself when you pop back to it?
I use - (void) viewWillAppear: (BOOL) animated in my upper level view controllers to refresh data after return from a lower level view controller.
I had thought about that, but I'll need to be able to find out whether any data has changed or not, as the reloading of data can take some time and it should only happen if anything has changed.
As the data structures for the table view are in the table view controller, I'll somehow need to access that view controller to tell it if anything's changed.
I had thought about that, but I'll need to be able to find out whether any data has changed or not, as the reloading of data can take some time and it should only happen if anything has changed.
As the data structures for the table view are in the table view controller, I'll somehow need to access that view controller to tell it if anything's changed.
The data is in which controller? The top one or the 2nd level one? Since the top one already has a pointer to the 2nd level controller, maybe it should query it to see if anything has changed? Then reload or not as needed.
This might be a good argument for moving the data to a data source object.
Well I have 2 seperate classes to hold the data, one class just holds the data needed to display a table row's worth (these objects are stored in first view controller), and the other holds the full object (with lots and lots of data) which is held in the 2nd controller. This is done for optimisation reasons as hundreds of records need to be pulled into the table. The root view controller just passes the record ID to the second view controller, which then pulls all the data required to display it in full.
Is this a good solution? I think if I could somehow reference any view controller at any time I could tell it that things have changed, and if so, what, so it immediatly knows what objects to reload with data from the database.
There must be a way of getting to all the view controllers precisely, and from anywhere in the app. Would it be a good solution to add pointers to the delegate to all the main view controllers in the app? It may only be 5 or 6, and these will always be retained by the navigation controller so there's no memory overhead at all?
This way, if you have an "update" method in that view controller, you can force an update anytime. And you might want that view controller to have a list of all it's sub controllers, and force each of them to do an update from that same method. Just iterate through the list, sending an update (or even just "reload") method to each.
You really don't want to be maintaining lots of view controller pointers in the different controllers, because it makes a real mess if you add or delete one.
It also sounds like you're using a database or some other external storage for your data, and accessing it from each view controller to get what that controller needs. I would suggest that you encapsulate all that in a custom class (model class for that data). Then if you need to change the storage mechanism for that data, only the one class needs to know. You might decide to do that to migrate to CoreData in 3.0, for instance.
This way, if you have an "update" method in that view controller, you can force an update anytime. And you might want that view controller to have a list of all it's sub controllers, and force each of them to do an update from that same method. Just iterate through the list, sending an update (or even just "reload") method to each.
You really don't want to be maintaining lots of view controller pointers in the different controllers, because it makes a real mess if you add or delete one.
It also sounds like you're using a database or some other external storage for your data, and accessing it from each view controller to get what that controller needs. I would suggest that you encapsulate all that in a custom class (model class for that data). Then if you need to change the storage mechanism for that data, only the one class needs to know. You might decide to do that to migrate to CoreData in 3.0, for instance.