On Jun 13, 2008, at 2:16 PM, Paul Archibald wrote:

The project I am working on is used to make and distribute copies of certain files. I am trying to add a module that will do some extra processing of the files, and then distributing copies of that new, processed file. I was given the interface (a window with a bunch of popups and stuff) for the new module in the NIB, and there was originally a category (AppController(ExtraCategory)) for the extra "module".

One typical case, and one that works well for a lot of folks, is something like this:

An independent window is described in its own nib. That nib may contain some NSController-derived objects for facilitating bindings. In your code, you define a custom subclass of NSWindowController that has the logic specific to that window. Let's call this class MyWindowController. In the nib, you set the class of File's Owner to be MyWindowController. You connect its "window" outlet (inherited from NSWindowController) to refer to the main window of the nib; likewise, you set the "delegate" outlet of the window to refer to File's Owner.

If MyWindowController requires access to any of the other objects in the nib, you declare outlets for them in the header and hook them up in the nib.

In all likelihood, the window described by the nib will need to present model data and/or allow the user to set model data. To accomplish this, MyWindowController needs to be the go-between. MyWindowController might receive a pointer(s) to the relevant parts of the model as an argument to its init... method. Alternatively, if the model is specific to the window, then MyWindowController could actually instantiate the model on-demand or during initialization. Either way, it needs to expose the relevant facets of the model through properties in its interface. (Not necessarily Objective-C 2.0 properties, but in the more general sense of the term.)

If you're using bindings, the NSController-derived objects in the nib will be bound to these model-revealing properties of File's Owner. The views will in turn be bound to the NSController-derived objects.

If you're not using bindings, then MyWindowController will contain glue code to respond to actions from the controls in the window by updating the model, and (vice-versa) respond to model changes by updating the contents of the views.

In your application controller, when it comes time to present this specific window, there will be code to instantiate an instance of MyWindowController. MyWindowController may be coded with knowledge of which nib it uses, or that information may be passed in to the initializer. Likewise, a reference to the model may be passed in. Then, the app controller would invoke -showWindow: on the MyWindowController instance.


I tried making a new controller for the new window/module, on the theory that since they don't share much data or functionality, they ought to be separate class objects. However, I am had some problems with that approach. In particular, I was getting several runtime errors of the type: "Could not connect the action someNSApplicationAction: to target of class MyController". I don't understand this at all, but I am more worried that I am just completely off track in trying to create a new controller, and that fixing this problem will just allow me to go even farther into the weeds.

This sounds like the nib you received had controls which were configured to deliver their action to the File's Owner target. When you change the class of File's Owner, you change which actions it responds to. These actions are/were part of AppController or its category AppController(ExtraCategory), but are not part of your new controller.

There are a number of possible solutions to this. Which you choose depends on the nature of the actions and the design of your app.

You can move the actions from the AppController to MyWindowController. (Or, in your case, copy them.) This requires that MyWindowController has the necessary knowledge and scope of influence to carry out the actions. It's possible for MyWindowController to simply forward the actions to the AppController instance (probably [NSApp delegate]), if necessary.

Another possibility is to take advantage of the Responder Chain's processing of actions. In this case, you reconfigure the controls in the nib to send their actions to First Responder. This causes the action to proceed up the responder chain in search of an object which can handle it. The window controller is in that chain, which is useful if you add the action implementation to it, which is similar to the previous approach. However, the application delegate is also in that chain. It's quite likely that AppController is already the application delegate, and so the action implicitly ends up where the nib was original sending it explicitly.

In IB 3.x nibs, there is a proxy for the application object in window nibs. Using this proxy as the target for an action is only useful if you've subclassed NSApplication, which isn't too common. (Remember, the application object and AppController are two different things.) However, it is possible to access the application delegate, which is often the application controller, through the delegate outlet of the application object. You can't target an action there directly, but it is possible to configure targets using bindings. So, it is possible to use bindings to configure a control so that it targets the application delegate, which is probably the same as AppController. This is quite convoluted and I don't believe it's common, but it is an option.


(And, a followup question would be: where could I find an example of an app that has multiple controllers which do not relate to the same document? The samples I have looked at so far seem to be based on the MCV pattern. I am looking for something more like MCV(1)+MCV (2).)

Well, for example, the code for TextEdit is installed with the developer tools. It's at /Developer/Examples/AppKit/TextEdit. Its Preferences.nib would be independent of DocumentWindow.nib, for example.

I hope that's helpful.

Cheers,
Ken
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to