small medium large xlarge

Back to: All Forums  Core Data
12 May 2010, 12:50
Lachlan Scott (16 posts)

I’ve rebuilt my application to use multiple XIBs backed with their own ViewControllers, largely so that I can swap their respective views in and out of the main application window at need, but have now encountered a design issue I hope someone may be able to help with.

The application’s ManagedObjectContext is loaded in the single App Delegate, and shared by all these views. It also provides outlets for all the ViewControllers and methods for loading their views into the main window. This seems sound.

But each ViewController/XIB has ArrayControllers for the same data, and often, I’m making KVC binding references across the objects to display and manage the data in the various views. And feeling rather dispirited by the amount of typing I’m having to do to maintain these bindings, I began to wonder if I was doing it wrong. (There should be a word for the sense of foreboding inexperienced Cocoa developers get when they think ‘this is all too hard; there must be some better way …’. ;-)

I first thought I should bind an ObjectController in the display XIB to the selected object from the pick list in the parent XIB, something like

objectController Value: delegate...selection

but I couldn’t get the values in the fields bound to the objectController to update properly. I spent the whole day working on it, reading and and trying to figure it out, but to no avail, and abandoned the approach.

So now I’m simply binding the text fields in one XIB to edit an object’s values selected from the arrayController in another XIB like this:

Text Field Value: delegate...selection.

(ie. delegate.clientListController.clientList.selection.firstName)

And it works, but if I’m going to do that, why not put the arrayControllers into the main XIB, provide outlets, and just reference them more directly; why bother putting them in the other XIB in the first place?


But something tells me I’ve got it all wrong. So I watched Lord of the Rings for a bit, as you do, and then thought Marcus and the lads would know the answer. So … can anyone help with this, please?

I want to reference various ArrayControllers from discrete XIB/ViewControllers; where should those ArrayControllers go?

Many thanks


17 May 2010, 08:17
Lachlan Scott (16 posts)

Ok, well after the outpouring of support from my peers, I was reading Marcus’ book again and realized that ivars in my main XIB delegate are available to every class in the application, and specifically the controllers I’ve written to back the XIBs through KVC like this:

@interface AppDelegate : NSObject {
	NSWindow *window;
	IBOutlet ClientPickListController *clientPickListController;

</small> ~~~ NSObject *pickListController = [NSApp valueForKeyPath:@”delegate.clientPickListController”]; ~~~

So I guess I don’t need to specifically do any more than that at the moment. But this does raise other questions for me.

a) how do I get a pointer to the controllers like that without getting compiler warnings, (since including the delegate header causes all kinds of horrible recursion) and b) this doesn’t seem like a very solid design to me, is it acceptable in Cocoa?



18 May 2010, 16:14
Marcus S. Zarra (284 posts)

One option would be to pass references down to the view controllers as you need them. This is the dependency injection design and it is used a lot on the Cocoa Touch platforms.

You should also reconsider your design. It sounds like you are putting a TON of stuff in the AppDelegate and that leads to a huge monolithic design that will be hard to maintain later. I recommend using the AppDelegate just to manage application level details like the starting and stopping of the application, etc. Create another controller to handle the Core Data stack and then pass that object around to the view controllers.

25 May 2010, 04:51
Lachlan Scott (16 posts)

Hi Marcus, thanks for your reply.

Ok, I’ll research dependency injection in Cocoa/Cocoa Touch, thank you.

Currently, the AppDelegate is not bloated actually, but I’m doing this KVC derived reference to methods in the delegate, which just can’t be the best way to do things. It also gives me compiler warnings, which isn’t fixed by using a @class declaration

Do you suggest that I put the Array Controllers in the Delegate, and hold a reference to the Delegate as an ivar in each View Controller, and use a ‘initWithDelegate’ to load the VCs with knowledge of the Delegate and hence ACs?

10 Aug 2011, 19:19
Igor Karelin (1 post)

I think you’d start reading NSPersistentDocument Core Data Tutorial: A Sheet for Creating a New Employee. The principles of share data between the main window and sheet are the same as with views. Each View controller must implement NSManagedObjectContext and ArrayControllers are placed in MainWindow. I think, creation of separate CoreDataController is not a good idea, because it’ll load all the data during it initialization process, but not sure about it.

I’m wrestling with the same task now, so share Your experience if you’ll realize it 1st :)

You must be logged in to comment