3

I have an AppController class that looks after view/control in my app in the usual way.

There's a button on my app's main window in IB that causes AppController to instantiate a new window controller (accountPanelController) and show that secondary window:

- (IBAction) showAccountPanel:(id) sender
{
    //Is accountController nil?
    if (!accountPanelController) {
        accountPanelController = [[AccountPanelController alloc] init];
    }

    [accountPanelController showWindow:self];
}

When that new window is done with, I want to send the data collected from my secondary window controller to a method in AppController:

- (IBAction) close: (id) sender
{
    NSLog(@"Close detected");
    [AppController addAccount:0];
    [self close];
}

However, when I try and call the addAccount method in AppController from the new window controller, I get an "'AppController' may not respond to '+addAccount'" warning.

This seems to be related to AppController being a class rather than an object instantiation, since the method in AppController is called -addAccount (rather than the +addAccount reported in the warning). Indeed, if I change the name of the target method to +addAccount instead of -addAccount, the warning does not appear (but the program crashes on execution).

Given that I don't actually instantiate AppController myself (I guess that happens somehow during NIB initiation), does anyone have any ideas how I can send the data to the AppController method? Notifications seem like overkill...

Many thanks.

Liam G
  • 107
  • 1
  • 9

2 Answers2

4

I recommend the following introduction article on Apple's Mac Dev Center: Communicate with Objects - #Notifications
Update:
I pointed the link to to relevant anchor (Notifications).

The problem in your code sample is, that you call a class method (those with a +), but you implement an instance method (-).
So a simple fix would be, to get the (shared)instance of your AppController (probably self in your code) and send it the addAccount: message.
But I encourage you to read the article first.

Maybe you can solve your problem by sending a notification (NSNotification) from your view to your controller.

Update:
Another interesting read for you might be this SO question regarding the difference between class methods and instance methods.

Community
  • 1
  • 1
Thomas Zoechling
  • 34,177
  • 3
  • 81
  • 112
  • Many thanks. I read all the links. The root is that AppController is a class I don't instantiate but which IBuilder points to for (IBAction)s. So I don't have a way to point to the instance that AppController produces when it is instantiated. Notifications work. Is there is a simpler way? Even Hillegass uses notifications in his chapter on panels. People must get data from a 2ary window in many apps so this must be common? I'm not familiar with shared instances and looked hard for some doc. Are you aware of any that might help? As below, I tried [self addAccount] no luck. Thanks Again. – Liam G Dec 24 '09 at 20:02
  • You probably could use [NSApplication sharedApplication], which is a shared instance of the application delegate. But I think using notifications is the right thing to do here. – Thomas Zoechling Dec 25 '09 at 10:14
1

Just supply an intiWithOtherController method and add it herre:

accountPanelController = [[AccountPanelController alloc] initWithOtherController:self];

just pass self, so you need something like this:

(AccountPanelController *) initWithOtherController:(OtherController *) 

now you have a pointer to otherController and you can do:

[otherController addAccount:0]
ennuikiller
  • 46,381
  • 14
  • 112
  • 137
  • Got this working. Nice and simple. Thanks. Only hitch is somehow keeping hold of the otherController pointer once the initWithOtherController returns so that I can use it in the close method of the Window. – Liam G Dec 30 '09 at 01:36