views:

110

answers:

2

In regards to XCode templates with CoreData enabled, I've read http://stackoverflow.com/questions/2729055/unclear-use-of-property-in-window-app-using-core-data which goes over the 'what' in the templates. But I am having an issue with the 'why'. By declaring the category in the implementation file, the CoreData accessors act like private methods. The problem with that is whenever you want to use CoreData elsewhere in your app, you need some extra code.

I've figured you need to either supply your own method that exposes the managed object context, such as...

- (NSManagedObjectContext *)getManagedObjectContext
{
    return self.managedObjectContext;
}

...which will allow other parts of your app to use it.

Or you would need to jam pack your app delegate with specific methods to return managed objects, ie getProducts or setUser.

Can anyone shed light on the reasoning here?

+1  A: 

If your project is big and needs to access the managed object context from outside of the AppDelegate, I would just move the property declaration of managedObjectContext to the header file, as in:

@interface myAppDelegate : NSObject <UIApplicationDelegate> {
    NSManagedObjectModel *managedObjectModel;
    NSManagedObjectContext *managedObjectContext;       
    NSPersistentStoreCoordinator *persistentStoreCoordinator;
}
@property (retain,nonatomic) NSManagedObjectContext*managedObjectContext;
@end

Then the other parts of the app can just use appDelegate.managedObjectContext. There's no reason to expose managedObjectModel or persistentStoreCoordinator outside the app delegate, though.

By the way I have a few comments about your usage of Objective-C:

Don't use get in front of the getter. For a property called foo, the getter should be

-(Foo*)foo;

and the setter should be

-(void)setFoo:(Foo*)_foo;

By convention, get... is used when a pointer is fed as a method argument, as in -[NSString getCharacters:range:] (See the Apple doc).

Follow the proverb, when in Rome, do as the Romans do.

Yuji
This sounds good, when I first starting learning this stuff I felt like I was discouraged from putting almost anything (aside from startup and shutdown calls) in the app delegate, maybe thats not totally the case.Thanks for the method naming tips too!
rob5408
+3  A: 

The reason for this is because you should be using dependency injection in your designs. This is the recommended design by the Core Data team. What is expected is that your app delegate will set the NSManagedObjectContext reference in your root view controller(s). From there the controllers will set or inject the necessary dependencies in the following view controllers.

This will lead to a more flexible design. I discussed it in depth in my article on the MDN (http://www.mac-developer-network.com/articles/cd0004.html).

Marcus S. Zarra
What happens when you rearrange your view controllers, and you have a tightly bound hierarchy of dependencies?
Alex Reynolds
Thanks for the article I'll check it out!
rob5408
That is why injection works because they are not tightly bound. The parent tells the child what to do. The child does not care if the moc is app wide or only exists for itself. This promotesreuse of views and ease of rearranging. Locking everything to the app wide moc does the exact opposite.
Marcus S. Zarra
I see a lot of people using the app delegate as some kind of global object store. Instead, as Marcus says, you should be injecting dependencies into your objects that need them (and due to the various ways objects in Cocoa can be instantiated, accessor injection is usually your best bet).None of the objects in your app should ever need to know about your app delegate; if they do, you should reconsider the design of your app.
Luke Redpath
Switched my accepted answer to this one as it's the correct approach.
rob5408