Domanda

So I'm a little confused here. I have a Cocoa app, in the appdelegate header I'm declaring a NSDrawer that I've connected in Interfacebuilder and whose contentView I'm setting programmatically depending on the context. The contentviews contain Buttons that are connected to various functions in the Appdelegate.

@property (strong) IBOutlet NSDrawer *theDrawer;

When my app starts app, and I inspect it in the Debugger "theDrawer" is not nil and correctly instantiated by the Interfacebuilder. In the

Now if the user clicks any button it turns out that references to [[NSApp delegate] theDrawer] will be ignored because theDrawer is nil. which doesn't make sense to me. I tried fix this by specifically setting the delegate when the app launches.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
  [NSApp setDelegate:self];
}

I've checked that self.theDrawer is not nil at that point. But even after I set the delegate explicitly, any future calls to [[NSApp delegate] theDrawer] are nil.

How can I make sure to access variables on my App delegate? My understanding was that calls to NSapp delegate will return a unique instance of the app.

It seems that when a user clicks on a button that this creates a new thread and NSApp delegate will return nil for all variables.

Any help appreciated

È stato utile?

Soluzione

The application delegate is properly set in main in main.m which you'll find in the "Supporting Files" folder of the project. Generally it's embedded in NSApplicationMain() which I believe references NSMainNibFile in the plist and actually has the main nib own the app delegate object instance. However Apple's not totally clear on how all that magic works. Nonetheless you can't set the delegate in applicationDidFinishLaunching -- that's a delegate function!

But if you're using a NSMainNibFile and a non-document application, the app delegate is likely being set to an object in your main NIB... in that NIB, the "File's Owner" is also the application delegate class, and the other outlets are non-nil within [NSApp delegate] because it's the main NIB file's owner. From the NSMainNibFile you can create outlets in the App Delegate class, because it's the file's owner.

If you create a second NIB, there are issues accessing the delegate. You don't want to create a object, because that isn't the same object as [NSApp delegate]. You can use the Application placeholder object and bind with a keypath of "application.delegate." But you can't create outlets because the app delegate can't be the file's owner.

But that's irrelevant, because if you have a second NIB that you're creating outlets for, they belong in a custom viewcontroller or windowcontroller subclass that you've declared is that file's owner. Even if that second NIB is loaded immediately, well then the app delegate should instantiate a controller instance to load and own the NIB, if you want outlets, it must be a custom subclass.

Apple sort of breaks this pattern by making the app delegate class the owner of the main menu "window" in MainMenu.xib in non-document applications... but that is because the menu window's a bit special. Anything you do outside of MainMenu.xib is going to need a custom controller class to have outlets.

Additional discussion in this answer about app delegate instances.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top