3

Within an application it's possible to have different UIViewControllers that need to share the same NSManagedObject. I'm usually do the following:

@interface CustomController : UIViewController

@property (nonatomic, retain) ProductNSManagedObject* productManaged;

@end

Then when I istantiate CustomController I inject it like the following:

customController.productManaged = ....

once done, CustomController is responsible to release it.

This approach works well (I don't know if is it correct), but what to do when a controller need that object but it's not a direct child of the controller that has that object? e.g.

MainController -> ChildController -> SubChildController -> ....

where MainController has the managed object.

Do I have to create a lot of intermediary properties or do I need to execute a fresh NSFetchRequest or something else?

The same aspect could be applied to the NSManagedObjectContext. Searching around I've found that the context can be grabbed from the application delegate that posseses it (if any). But this approach lacks of flexibility as Marcus Zarra wrote in passing-around-a-nsmanagedobjectcontext-on-the-iphone.

Any suggestions? Thank you in advance.

Lorenzo B
  • 33,216
  • 24
  • 116
  • 190

2 Answers2

2

I create a singleton object that contains the managed object context that will be used throughout the application. I put any supporting code related to the data (e.g., persistent store coordinator) inside this singleton and keep all of the view and controller information separated from it.

In one case, I need a managed object context for another thread. It became apparent that it would be useful to refactor and put that context inside the same singleton. Then merging between the two contexts can be done inside the singleton.

This has helped me manage my code. You might consider it.

Jim
  • 5,940
  • 9
  • 44
  • 91
  • +1 for your advice. But what about **NSManagedObject** objects? Dou you know the correct way to pass them among controllers? Thank you. – Lorenzo B Feb 23 '12 at 20:13
  • 1
    Generally I use a fetched results controller for each view controller. It keeps track of the managed objects that are important to that particular view. The fetched results controller is bound to the managed object context through the singleton. This way, if the managed object context changes through actions in any view, the frc's bound to the other views can respond and call their delegate methods. – Jim Feb 23 '12 at 20:32
1

This is a very common question (see here and here for related ones). As I wrote in the answers for the related questions, you should stay away from singletons and create a separate object that will take care of object instantiation, of creating the object graph for your application. This separate object can hold references to all shared objects and supply them to the objects being built, so that none of your regular objects has to keep a reference to something just to pass it as a dependency to other objects. See this blog post for more rationale against singleton misuse and for further pointers, especially the articles by Miško Hevery.

I have created a sample Xcode project that shows how to wire an app without singletons, keeping the coupling low and resolving other singleton issues. It’s very simple at the moment, I will add more common use cases later.

Community
  • 1
  • 1
zoul
  • 102,279
  • 44
  • 260
  • 354
  • Thank you for your reply and +1 for your suggestion. But what do you mean with *This separate object can hold references to all shared objects and supply them to the objects being built, so that none of your regular objects has to keep a reference to something just to pass it as a dependency to other objects.*? Maybe when you will create your sample project, let me know. – Lorenzo B Feb 24 '12 at 08:41
  • I've just finished reading your answers. They are useful. The approach seems to be very clean but what I can't understand is how to reference the object *factory* that is istantied with *Factory *factory = [[Factory alloc] init];* throughout the application. Thank you again. – Lorenzo B Feb 24 '12 at 08:48
  • Your sample project is clear to me. The aspect to work with an object graph is could be considered like the Core Data solution and I like it. My next step is to applied your pattern to managed object. Could you suggest me the right way to do this? For example, what a *Factory* class would create? Thank you in advance. – Lorenzo B Feb 25 '12 at 10:42
  • 1
    If I understand the issue correctly (I’m not familiar with Core Data), your managed object is simply something you need to share between more controllers. In that case it’s something like the `Logger` class from the sample project: the Factory should create an instance of this object when it starts, keep a strong reference to it and pass the instance to whoever needs it. – zoul Feb 25 '12 at 11:21