PDA

View Full Version : Why can't I subclass NSApplication?




DavidCar
Mar 6, 2006, 11:34 PM
I can't figure out how to post and catch "NSApplicationDefined" events. The problem is in just demonstrating that I can intercept any event. To do this I am trying to subclass NSApplication, but I can't make the project accept the subclass. The following appears in "Interface Builder: Frequently Asked Questions"

"Many widgets have a Custom Class pane in the Info window. You can use this pane to specify that, at runtime, an object should be instantiated as a specific subclass. For example, you could make a subclass of NSApplication called MyApplication. To ensure that an instance of MyApplication is used at runtime, click the File’s Owner of your main nib file. Bring up the Custom Class pane and select MyApplication."

My project was created as a "Cocoa Document Based Application" and the closest thing I can find to a "main nib file" is MainMenu.nib which does have a "File's Owner" but applying the above Custom Class pane procedure and then running the program with the following subclass produces no NSLog messages during key or menu events. Where am I going wrong?

#import "MyApplication.h"

@implementation MyApplication

- (void)sendEvent:(NSEvent *)theEvent {
NSLog(@"This is getting sendEvent:");
[super sendEvent:theEvent];
}

@end


BTW, I was originally trying to call NSRunAlertPanel from multiple subthreads, guarded by NSLock, but had some unexpected problems when all my threads locked up and my alert panel only partially displayed. I'm trying to solve that by calling all NSRunAlertPanels from the main thread via an application defined event, passing the information by subclassing NSEvent, and delaying the subthread with an NSLock until the AlertPanel is OKd. I didn't expect to have problems just positioning a method to intercept events.



robbieduncan
Mar 7, 2006, 03:53 AM
I've no idea what you have done wrong! You should be able to subclass NSApplication (I can).

First of all create a new class in your project called, say MyNSApplicaion.

The header should be something like:

@interface MyNSApplication : NSApplication

...

@end

Now in XCode select your app in the Targets section and bring up the Target Info pane. Choose Properties and change the Principal Class to MyNSApplication.

This is optional: it works without it!
Now open MainMenu.nib. Drag the header into the window titled MainMenu.nib (English). Switch back to Instances from Classes. Select File's Owner and open the Inspector. Change the Custom Class to MyNSApplication.

DavidCar
Mar 7, 2006, 10:08 AM
...
Now in XCode select your app in the Targets section and bring up the Target Info pane. Choose Properties and change the Principal Class to MyNSApplication.

This is optional: it works without it!
...


I left my original MyApplication file unchanged, but did what you said about Principal Class in Properties in the Targets Info pane. That solved the problem. Thanks, thanks, thanks.

Interface Builder is still a mystery to me, as I only use it when I have to. I couldn't seem to find a good reference on the internet that would give me the essential scrap of info you just gave me.

DC

kikoalbiol
Apr 22, 2011, 02:48 PM
Try implement:

+(id)sharedApplication
{
return [[MyApplication alloc] init];
}

wolfiexiii
Apr 22, 2012, 01:33 PM
Try implement:

+(id)sharedApplication
{
return [[MyApplication alloc] init];
}

The above does not function - tries to create multiple application instances. Instead the following works.

+(id)sharedApplication
{
return [super sharedApplication];
}