views:

162

answers:

4

Update! I've created a sanitized test program that illustrates the issue.
Here you can view a PDF of exactly what I've done, and download a .zip of the project

Update2! See the comment thread of Conceited Code below to understand more about this problem.

Update: Added bounty, I'm looking for an explanation of what's actually wrong with my example, what fixes it, and what design better suits my purpose than the current "LoadNib_Controller" (see Conceited Code comment discussion)

I get a runtime error message " [<My_WindowLoader 0x100228ba0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key managedObjectContext. "

My_WindowLoader has a reference to My_AppDelegate (which I've debugged and is definitely set up properly). It also has a few My_WindowController *'s.. which are My_WindowController : NSWindowController. They are used so that I can provide a property (managedObjectContext) to Windows that load up as I load nib's up, so that I can set up my Core Data bindings. They look like..

.h:
@interface My_WindowController : NSWindowController {

NSManagedObjectContext *managedObjectContext;

}

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

.m
@synthesize managedObjectContext;

My_WindowLoader loads a nib in the following manner:

Window1_WindowController = [[My_ WindowController alloc] initWithWindowNibName:@"Window1" owner:self];
// The following line I have debugged and it does in fact go to my app delegate, wherein it instantiates a MOC (since this is the first place in the code that it's used..), and returns it, and it appears to also be setting it via the property in My_WindowController
[Window1_WindowController setManagedObjectContext:[AppDelegate managedObjectContext]];

// The following is where I get my problem, this does load my window but in my gdb window I see the runtime error message that I list at the top of this post 
NSWindow *window1Pointer = [Window1_WindowController window];

To get the above runtime error, within my Window1.nib I have array controllers that bind their Managed Object Context to "File Owner" with model key path "managedObjectContext". File's Owner is type My_WindowController

Obviously something is wrong but I've stepped through it with a debugger as well as using common sense, and it all seems like it should work. I see most "this class is not kvc.." errors stem from misnaming stuff in IBOutlet/IB etc but I have triple checked all of that here and I have ensured that I completely quit and restarted Xcode/IB and have the latest loaded.

A: 

Does your NIB have an NSWindow correctly connected up to File's Owner (Window1_WindowController)?

jrtc27
I have linked file's owner "window" to the NSWindow for Window1.. That's all I have set. If I go in to the Window1 nib and unbind my NSArrayController's managedObjectContext then my code (My_WindowLoader calling [Window1_WindowController window]; does in fact load and display the window1
Nektarios
+1  A: 

The problem is being caused by the NSArrayController in the new window that you have binded to your managedObjectContext. If you uncheck "raises for inapplicable keys" the error becomes "Cannot perform operation without a managed object context". I believe there is something wrong with the managed object context in your class.

EDIT: see comments

Conceited Code
Yes I understand that part, but why? I need the MOC to be available to NSArrayControllers in nib's other than MainMenu.nib
Nektarios
Updated my answer. Not quite sure what the problem is yet. managedObjectContext probably isn't valid for some reason.
Conceited Code
Sounds like you may be on to something, interesting that the error changes in that case
Nektarios
Next time you do this, keep in mind that it is MUCH easier to debug problems like these if you use more code instead of interface builder and separate as many windows as you can into more nibs. I would have created the first window in its own NIB and have the delegate open it and set a managedObjectContext in that. That way when the next window is opened you can just pass the managedObjectContext on instead of referencing the delegate.
Conceited Code
Finally got it to work! There has to be a problem with the way you are connecting the delegate to the LoadNib_Controller. If I take the exact same code and add it to the delegate and connect the button to the method in the delegate and completely remove LoadNib_Controller then it works perfectly. The way you had it set up is really confusing and I am not exactly sure where the problem is, but if you follow the comment I put above then we could probably find the problem (separate the window from the menu and don't access the app's delegate directly).
Conceited Code
So instead of having a controller that handles loading up nibs, put all of that code/logic in MOC_Issue_Example_AppDelegate directly? Is that good practice? I agree with all your thoughts and will try this tomorrow and will post back, thank you
Nektarios
No. Have the delegate open the first window (its in another nib and its file owner is the controller). Then have the window control opening more windows. The delegate should really only be used when loading and saving core data.
Conceited Code
Ok - I'm with you. I need to explain more of my real situation to move forward. In reality I launch Window1 by the following: Under "Window" main menu topic, I have an entry "Window1" "Window2" .. etc. I have THOSE events call a method on LoadNib_Controller to raiseWindow1. So there's really no window with a button that says "Open Window1" - instead this is achieved by my MainMenu bar. So I can't go the route of a separate .nib for the "launching window" as suggested. Maybe my explanation clarifies why I went the route I did with LoadNib_Controller existing..
Nektarios
A: 

Your file's owner is the wrong object. It's supposed to be the window controller, the one with the managedObjectContext property. Why did you make a separate controller to load the nib? That's not standard practise. NSWindowController is designed to load its own nib. It should be the file's owner. It should be instantiated with [[MyWindowController alloc] initWithNibName:@"MyWindow"].

Bored Astronaut
I subclass NSWindowController and simply add a property so that it can be passed a reference to the MOC. How can I pass the moc in without subclassing NSWindowController to support that?
Nektarios
+1  A: 

Thanks to #cocoa on freenode, my issue is that I'm doing:

Window1_WindowController = [[My_ WindowController alloc] initWithWindowNibName:@"Window1" owner:self];

I should be doing

Window1_WindowController = [[My_ WindowController alloc] initWithWindowNibName:@"Window1"];

Note the difference with initWithWindowNibName: vs initWithWindowNibName:owner:

Furthermore, the right place to put this code is in AppDelegate, it's the App controller and this type of logic is at home there.

Nektarios