views:

138

answers:

5

main.m

#import <Cocoa/Cocoa.h>

int main(int argc, char *argv[])
{
    return NSApplicationMain(argc,  (const char **) argv);
}

CoolClass.h

#import <Cocoa/Cocoa.h>

@interface CoolClass : NSObject <NSApplicationDelegate> {

}
- (void) applicationDidFinishLaunching : (NSNotification *) aNotification;
@end

CoolClass.m

#import "CoolClass.h"

@implementation CoolClass
- (void) applicationDidFinishLaunching : (NSNotification *) aNotification {
    NSLog(@"THIS SHOULD BE PRINTED TO THE DEBUG CONSOLE");
}

@end

I tried this with "applicationWillFinishLaunching" as well, but still no luck. Any help at all would be appreciated. Thanks.

+6  A: 

You should define your CoolClass as applications delegate in Interface Builder (Ctrl+Drag from App instance to your CoolClass instance

Eimantas
Alternatively, you can call `[NSApp setDelegate:self]` in the `-init` method of `CoolClass` if you want to do it programmatically.
Rob Keniger
Ah, just saw the above comment. I will try that.
demonslayer319
I currently have:CoolClass.m#import "CoolClass.h"@implementation CoolClass- (void) init{ [NSApp setDelegate:self]; NSLog(@"THIS SHOULD BE PRINTED TO THE DEBUG CONSOLE");}@endBut it still won't run. I have modified CoolClass.h to reflect this too.I'm confused by the above answer. What am I supposed to drag, and where?
demonslayer319
Drag [Object] from component library in interface builder to your MainMenu.xib.Then in identity inspector set its class to CoolClass. And then do ctrl+drag trick.
Eimantas
+1  A: 

applicationDidFinishLaunching is an instance method, not a class method. That is, you'll need an instantiation of your class to receive that message. Plus, it can't be just -any- instantiation; your application needs to know about your instantiation and know that it's supposed to send delegate messages to it. The easiest and most common way to do this is...

First, you'll instantiate your CoolClass. Open your application's MainMenu.nib file in Interface Builder. Drag an "Object" (it'll look like a blue cube) out of the Library window. Select it and use the Identity tab of the Inspector to change its class from NSObject to CoolClass. Now, you have an instance of your CoolClass.

Now, you'll set that instance as the application's delegate. Control-drag from "Application" (still in Interface Builder) to your new instance of CoolClass. A window will pop up (showing outlets of Application that could be connected to your object). Choose "delegate". Now your application has an instance of your CoolClass set as its delegate, and thus, your applicationDidFinishLaunching will run.

andyvn22
You'll get compiler warnings if you adopt <NSApplicationDelegate> and don't implement `-applicationDidFinishLaunching` (the instance method with selector @selector(applicationDidFinishLaunching)), but if you implement `+applicationDidFinishLaunching` (the class method with selector @selector(applicationDidFinishLaunching)) and set the class itself as the application's delegate (`[[NSApplication sharedApplication] setDelegate:[CoolClass class]]`), the application object will send the message to CoolClass itself.
Jeremy W. Sherman
+1  A: 

What you're missing is that adopting the protocol makes objects of kind CoolClass ready to function as delegates of any NSApplication object (provided you follow through on the declaration and implement all required methods of the protocol). Declaring conformance to the protocol also prevents compiler warnings when you set instances of the class as an application's delegate.

But for a specific application object (say, the shared NSApplication object that Cocoa creates for you) to know to send messages from the protocol to a specific CoolClass object, you must set the object you want to receive those messages as the specific application object's delegate.

What this means is that some time before the messages you want to receive would be sent by the application, something needs to instantiate a CoolClass object - call it c - and tell the application, "Hey, your delegate is c over here, so send delegate messages to the little feller from now on."

What that boils down to is that these lines of code must execute before the application finishes launching:

CoolClass *c = [[CoolClass alloc] init];
[[NSApplication sharedApplication] setDelegate:c];

The easiest way to have this happen is to let Interface Builder do the work for you: let the MainMenu nib instantiate your CoolClass and also set the cool class object as the application's delegate when the nib is loaded, as others have suggested.

To do so, open MainMenu.xib. Drag a Custom Object into the xib and change its class to CoolClass in the inspector. Ctrl-drag (or right-click drag) from the application object in the xib to the CoolClass object and choose "delegate". Save, build, and run.

Jeremy W. Sherman
A: 

I appreciate you may be trying to learn from scratch, but why did you not just create a new project using one of the XCode templates? It sets all this up for you to begin with. Life involves enough debugging without having to add more atop it!

Kendall Helmstetter Gelner
A: 

To start at the beginning: your call to NSApplicationMain should be wrapped in an NSAutoreleasePool. You will be in trouble if you don't do that.

St3fan