Re: fundamental question: how do I call controller methods from other classes?
Re: fundamental question: how do I call controller methods from other classes?
- Subject: Re: fundamental question: how do I call controller methods from other classes?
- From: Adam Leonard <email@hidden>
- Date: Wed, 21 May 2008 22:38:53 -0700
Hi,
Ok, so your approach works, but as you already see, it has problems.
You are totally right that it is best to keep your models uninvolved
of the GUI, and therefore you should not be creating instances of them
in IB.
First, I would read through the MVC (model view controller)
documentation: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/chapter_5_section_4.html
Basically, you should not be coding your models such that they rely
exclusively on a specific GUI controller.
In your example, by having the model call -showStatus on the
controller, the model is well, controlling the controller and breaking
it's role as a model, which is just to store data and do stuff with it
when told by a controller.
If I understand what you are trying to do, the socket model class is
told to do stuff in the background, and when it's status changes, you
want that change to be immediately reflected in the UI.
The most common solutions to this problem are delegates and/or
notifications.
Delegates:<http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html#//apple_ref/doc/uid/TP40002974-CH7-SW18
>
Notifications:<http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_7.html#//apple_ref/doc/uid/TP40002974-CH7-SW7
>
The documentation covers all the basics.
In either case, you should instantiate your controller class in IB (as
it relates directly to the GUI) and your socket model objects in code
in the controller class.
If you used delegates you would:
1. Add accessors for a delegate pointer of type id (so the delegate
can be any object). You can also create a special initializer, like -
(id)initWithDelegate:(id)aDelegate;
2. Create the socket model object from the controller object, probably
in -(void)awakeFromNib; (called when the nib file has loaded and
connections have been set up). Assuming you created a special
initializer, you would do mySocket = [[POSSocket
alloc]initWithDelegate:self];
3. Declare a -(void)statusDidChange:(NSString *)statusString; in an
NSObject category (see the linked documentation)
3. When the socket changes status, you would call [delegate
statusDidChange:newStatus];
4. Make the controller (the delegate ) implement the -statusDidChange
method to tell statusField to show the new status.
For notifications you would:
1. Create the socket model objects in the controller object, also
probably in -awakeFromNib
2. In the controller's -init or -awakeFromNib method, register itself
as an observer for a notification, using your showStatus: method as
the selector to call when the notification is received.
3. When the socket changes status, you post the notification under the
same name the controller registered it under. You can use the userInfo
dictionary to add an NSString containing the new status.
and I am feeling quite
dumn here.
You shouldn't. This is a tricky topic. You should only feel DUMB for
spelling it wrong :)
Adam Leonard
On May 21, 2008, at 8:15 PM, Matthew Youney wrote:
Jens, Shawn,
Thanks.
I have my application working, however not exactly as I would like.
What I
did was, in IB, created a NSObject, and set it to my POSsocket
class. I
understand now that IB "automatically" instantiates this classes
that you
put in there. I added the required outlets, and I can do what I
need to do.
I would prefer to separate I/O activities, business logic, etc from
the GUI,
as well as be able to instantiate objects programmatically, and that
is what
I have been attempting to do, I just have no mechanism of sending
messages
to my "controller" class from my "model" objects unless the
"controller"
makes the call.
I guess I just have to get my head around it, and design
appropriately.
Again, thanks so much for your help,
Matt
-----Original Message-----
From: Jens Alfke [mailto:email@hidden]
Sent: Wednesday, May 21, 2008 10:06 PM
To: email@hidden
Cc: email@hidden
Subject: Re: fundamental question: how do I call controller methods
from
other classes?
On 21 May '08, at 5:07 PM, Matthew Youney wrote:
The name of the controller object in interface builder is
myPOSsocketController, and the following gives the compiler error
"myPOSsocketController undeclared or first use in function"
If you want an object in a nib to know about another one, then modify
its class to add an instance variable declared as an IBOutlet:
@interface POSocket
{
...
IBOutlet POSocketController myController;
Save the .h file and IB will now know about that outlet, and you can
control-drag from the POSocket to the controller and assign the
myController instance variable.
Typically what happens is that you have a controller object (often an
NSWindowController) that's the nib's owner, and you add outlets to it
for all the other nib objects you need to reference directly. It's
rarer for other objects in the nib to have outlets pointing to each
other, but it happens sometimes.
-Jens
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden