Nil out NSFetchedResultsController Delegate when offscreen? - ios

Is it best practice to Nil out NSFetchedResultsController Delegate when offscreen?
For example, I have a list managed by a NSFRC. When I tap a list item, I get a detail view. I can potentially change something on a detail view that will remove it from the list. Or, if I continue to slide through the detail views, I can cause it to load in more data (which would subsequently update the parent table view NSFRC).
I'm getting strange behavior when I DO nil it out. Can't seem to find advice on this anywhere.

No reason to nil out your NSFRC here. In fact, this is the main convenience of having your tableView managed by an NSFRC, is that it will update itself appropriately while you are off in other views changing data. This also applies data changes sequentially, rather than having to refetch all data when returning to your list.

I have posted a similar question time ago, looking for a technical explanation of this 'best practice'. However I didn't find anything.
I suppose that much of the suggested 'best practices' came from older iOS version, where viewDidUnload could have been called in case of memory warning, but that's not the case anymore.
In my experience, I found out that it is only mandatory to resign in case of background update and merge. All the other case depends on your application logic.
For example when you have nested CoreData entities with subsequent UIView, like so:
child1 (UITableView)-->child2 (Detail)-->child3 --> (UITableView)-->ecc...
Then, a change on child3 will have the child 1 table view react on that change, so you may want to avoid unnecessary call to a remote fetched controller, by resigning as delegate or introspecting the changement and returning YES or NO within the delegate method. It could be simpler and much efficient to refetch the query.
Keeping the same structure, suppose you have a mass update on latest UITableView by merging two context, if you have used the same context for all the controllers, then they will be trying to update its view even if not needed.
So for a simple case like UITableView-->UIView (detail) I can see no problem of keeping delegate assigned, all the other case, I would do a little analysis.

Related

How can I recycle controllers in UICollectionView's cellForItemAtIndexPath?

I am displaying a number of cells, whose content is reasonably memory intensive. I have a custom controller that sets up a view to display the content, and updates the UI periodically. However, often UICollectionView asks for a particular cell several times. I want to know how to design (well) a system to re-use the controller + view if I have already created it for a given piece of data. I thought about storing a controller reference in the data object, but don't know if storing UI elements in what is meant to be data is a good idea. Also, if I did this, I would need to monitor retainCount on cell unload, and when it gets to '1', remove it from the data object, which seems a bit hacky. Similarly, a NSDictionary of data->controller pairs in the UICollectionView could also work, and would again require monitoring retainCount, or re-implementing a retain counting mechanism for my particular case. It's doable, but seems clunky.
I'm very new to ios, so it may be I'm approaching this all wrong. Any suggestions are greatly appreciated!
First of all, think if displaying a controller view inside a cell is a good idea. I'm not sure, but since i'm not familiar with your project, it's something only you can tell.
Secondly, You can create your own pool of controllers. When you need a controller to put inside the cell (in cellforIndexPath method), take one from the pool. If the pool is empty, create a new one. The cell shouldn't come with a controller of it's own, put it only in cellForItemMethod.

Data management across segues

This is a concept question.
Like many others, I have a parent scene and a child or detail scene. When I click on a specific button in my parent scene, prepare to segue gets called and I pass over a couple of properties. In my detail scene, I gather more information and need to save it for use by the parent. I have seen various methods involving delegates, using singletons, and passing directly back to the parent properties. Here is my question, would it be more correct to store the data in a database in the detail controller, or pass it back to the parent controller to store it? It seems to me that since it was collected in the child, it should be stored there.
Would that be the more correct way of handling it?
For simplicity, say the larger model is an array of custom objects and the detail view presents and edits one of those objects. If you pass a custom object to the detail vc on before the segue, there's no need to "pass it back" later. The parent vc passed that object in the first place, so we know it already has a pointer.
Instead, the parent vc should notice that the work has been done on the object it passed and react accordingly (usually update it's view) This can be done by one of a handful techniques:
just assume something changed and update the view on viewWillAppear
notice the custom object changed via KVO (observing one of its properties)
be notified that the object changed because the detail vc posts an NSNotification
learn that the object changed by arranging to be the delegate of the detail vc
pass the detail vc a block to execute when it updates the custom object
It's hard to say what's better without knowing more about your situation. I can say that simple is usually better, and that favors (1). I can also say that delegates are fine, but often overused.
If you're dealing with more than a few pieces of information, it would likely be much easier in the long run to use Core Data. If, down the road, you decided to add more functionality to the app, or wanted to store different kinds of information, it would take no more than a few extra lines of code to do this.
But from what it sounds like, you have a really simple app, so you should probably be fine just making an instance of your "parent scene" in your "detail scene" and storing whatever values you may have in the "detail scene" into properties that already exist in the "parent scene".
Does that answer your question well enough?

UITableView - Delayed update when using sections

I've been searching for a few days, and have continued to learn from reading the apple docs and various tutorials, but there's a problem which I can't seem to get a handle on.
I have a simple app that keeps track of projects, with a single Core Data Entity (ProjectEntry). All the attributes are strings at the moment. It's basically a combination of Paul Hegarty's Core Data lectures and Tim Roadley's web tutorial.
I can add and save Entities and populate a tableview with the data. For the moment, I'm using the CoreDataTableViewController subclass that Hegarty provides in the lecture. I'm mentioning that because...
When my UITableView isn't divided into sections, the new information "instantly" appears in the UI after adding a new entry. However, when I add sections ( via sectionNameKeyPath), the new data still saves, but shows up only after refreshing several times OR waiting 30 seconds before refreshing(via a pull-to-refresh mechanism, which Hegarty also provided).
The tableview delegate methods all seem to be working, as do the NSFetchedResultsController's methods. Using the Stanford/Hegarty CoreDataTableViewController subclass in the past has yielded success, and I've learned a lot reading through the implementation file itself.
The controllers are embedded in a Navigation controller, with the managed object context being passed among the controllers via the prepareForSegue method. Some simple logging shows me the managed object context, initially obtained via a UIManagedDocument, is being successfully passed along.
I've tried the [self.tableview reloadData] and/or the beginUpdates/endUpdates in viewWillAppear, but the delay persists.
What is it about dividing the tableview into sections that's causing the delay? Would calling reloadSections on the tableview be necessary? Like I said, the entries are saved with Core Data and the fetchedResultsController populates the non-sectioned tableview instantly...
It's probably something obvious that I'm just missing, but any help would be appreciated.
Warren Burton's comment above made me re-check if my managed object context behavior was consistent while being passed among the view controllers via the prepareForSegue method.
So, as mentioned in my last comment above, it seems to solve the problem for the moment:
from above:
The initial view controller is non-tableview, which can segue to a UIViewController to add a ProjectEntry, or segue to a UITableViewController which lists saved project entries. This initial view controller creates or uses the UIManagedDocument. By setting a one-line check to see if the UIManagedDoc is being used in this initial view controller's viewWillAppear method, the "delay" in displaying new section data in the tableview seems to stop. I'll test it some more before saying the issue is solved. This way, the shared managed object contexts seem better "bound together" via the managed doc - vapul

What is the appropriate design pattern for the following situation?

As an exercise I am working on a simple drawing app for the iPad.
I am using UISplitView, with the drawing view as the detail view. In the master view controller I present (in a table view) a list of the shapes drawn so far.
The user can edit or delete any shape from the master view controller, and also select and edit a shape by touching it in the detail view controller.
To notify each of the view controllers of the changes made by the other, I thought of using delegates, but I am not sure if this is the right pattern to use.
First, as I understand it, delegates are supposed to be used when a certain object encounters an event which they don't know how to handle. in that case they pass all the information to the delegate and let it handle the event. This is not the case here since both view controllers need to do something with the information. Using delegates here can cause code repetition.
Another reason I am thinking not to use delegates is that in the future I might want other view controllers to get the information of changes in the drawing. I can use multiple delegates (is it good practice in general?) but I'm not sure this is a good solution either.
Are there other solutions I should consider?
On the contrary, I think delegates might be the right pattern to use here - you don't necessarily delegate only when you can't handle an event (though that might be one situation where you would delegate).
Instead, consider delegates a way of getting information to or from another object, when you simply don't know what that object might be. For example, Apple uses the delegate pattern when working with UITableViews; in that delegate protocol, the table view knows perfectly well what to do in each situation, but still notifies your code when certain actions are about to happen. I think that's an excellent parallel for your situation. (Note that a parallel to your question's assumptions also exists, in the UITableView "data source," where the table view does require some bits of information.)
Another technology you could consider using, if you're really dead-set against delegates, would be to use notifications. You can have each controller subscribe to particular notifications, then have your shape (or detail view controller) post instances of NSNotification when observable changes happen. That way, you still get to handle events happening in a different controller, but without needing to maintain a delegate list.
As for code duplication, just consider refactoring as you start encountering situations where you would duplicate; maybe you should design a single delegate or notification subscriber object for the common code, then only do class-specific things in each of the other controllers?

Is this the correct "layout" for delegation?

I'm building a simple calendar application based in a single view controller. The view controller has a hierarchy as follows:
CDViewController
CalendarView
EventView
AgendaView
TPKeyboardAvoidingTableView
EventInfoCell
My question specifically pertains to the EventInfoCell within my AgendaView. The Cell has various ways of laying out textFields and textViews, depending on the information that needs to be displayed. These textfields and textviews are enabled/editable based on the tableview's edit status and edit/delete core data objects. When the strings within these change, the cell needs to alert the managedObjectContext to save or delete an object, update the model within the agendaView that populates it's tableView, and update the model that pertains to all events for the calendar. My current configuration makes the viewController the delegate of EventInfoCell, but this complicates the update for the agendaView model. It seems almost counterproductive to set the EventInfoCell delegate to be the AgendaView, tell it when information changes, and then have the AgendaView pass the word on to it's delegate (the viewController), but if it is more compliant to MVC than bypassing the agendaView altogether, I will gladly implement it. I'm trying to figure out what is the better design pattern, any input is greatly appreciated.
"It seems almost counterproductive to set the EventInfoCell delegate to be the AgendaView, tell it when information changes, and then have the AgendaView pass the word on to it's delegate"
Why does this seem counterproductive? This is the way I would handle it. If you don't do it this way then you are going to have to open up some sort of properties or a notification or something in the AgendaView for the ViewController to pass the information back to it. That sounds more counterproductive to me than passing the information up the chain. Plus, you may eventually have some sort of changes in the EventInfoCell that require its delegate to act, but do not necessarily alter the Core Data model. So, I think you should pass the delegation up the chain.

Resources