0

Unannounced, the 2 notices in the image below were discovered while searching for why -applicationShouldTerminate: is not being called in AppDelegate.m on quit (Cmd+Q). It worked some time ago.

Hovering over the two yellow triangles reveals:

  1. NSObject does not have an outlet named delegate.
  2. The action 'terminate:' is not defined on 'NSObject'.

Xcode is not showing errors or warnings and the app builds.

-applicationShouldTerminateAfterLastWindowClosed: IS called within AppDelegate.m when the red dot of the window is clicked.

MainWindow.nib view

My experience with Cocoa is thin (learning). I've compared the connections for File's Owner, Application and App Delegate in 2 other projects, and think a missing window outlet might be the cause. The notices above point to something else.

I would like to make sure the connections are correct as a first step. How do I repair this?

Edit: Add image of Main Window Controller connections

Main Window Controller info

Edit 2: Add image of File's Owner connections

enter image description here

David
  • 3,285
  • 1
  • 37
  • 54

1 Answers1

1

In the main NIB of an application, the two placeholders, File's Owner and Application, both end up referring to the same object. That object is the application object, the sole instance of NSApplication or a custom subclass of it. The Application placeholder is always holding the place of the application object because that's its purpose. The File's Owner placeholder is holding the place of whatever object is specified as the NIB's owner when it is loaded at run time. When Cocoa loads the main NIB at application startup, it specifies the application object as the owner. For other NIBs, File's Owner will likely be some other object.

However, Interface Builder doesn't know that a given NIB is the main one. So, it treats those two placeholders independently.

I don't know why Interface Builder has taken to setting the class of the Application placeholder to NSObject. It should really be NSApplication. That's why Interface Builder doesn't realize that the application object has a delegate outlet and an action method -terminate:.

As it happens, the class of File's Owner is properly set to NSApplication.

So, there are two ways to fix this:

  1. Set the class of the Application placeholder to NSApplication or, in the rare case that you're using a subclass, that subclass.
  2. Disconnect those connection from the Application placeholder and connect them to File's Owner instead. This is the way that the standard project templates do it.

For any given main NIB, you should probably standardize on using one or the other but not both. That is, one or the other should have no connections. That way you avoid conflicting or redundant connections.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • Great explanation. Thank you Ken. – David Oct 05 '15 at 00:33
  • Trying to implement your suggestion, I hit a snag. The `-terminate:` method will not connect as an outlet of Application to File's Owner. Is this because the class of File's Owner is `MainWindowController`? In another app, the File's Owner (placeholder) is of class NSApplication and Application (placeholder) is of class NSObject. – David Oct 05 '15 at 00:39
  • If this is the main NIB of your app, then the class of File's Owner should be `NSApplication`. You would only use a window controller class as the class of File's Owner for a window NIB. Just to be clear, `-terminate:` is an action method, not an outlet. Target-action connections and outlet connections are both kinds of connections, but they are different kinds. – Ken Thomases Oct 05 '15 at 01:00
  • I followed these steps: 1. Changed File's Owner class to NSApplication. 2. Deleted the 2 connections (with alert) in Application. 3. Make outlet connection from Application to File's Owner -> delegate. Result: Quit is greyed out. I cannot quit the app. – David Oct 05 '15 at 01:10
  • Ken, can you take a look at the edit above of the MainWindowController object of MainWindow.xib? – David Oct 05 '15 at 01:17
  • You need to connect the Quit menu item's sent action to File's Owner, with action `-terminate:`. – Ken Thomases Oct 05 '15 at 01:18
  • OK. That works! And you've answered the question I asked. However, all of this has not caused a break at either of the two `-applicationShouldTerminate` methods. That's what I want to restore. – David Oct 05 '15 at 01:22
  • You need to show that method. You probably misspelled it slightly. For example, in your last comment just above, you wrote it without the colon, which is an integral part of its name (`-applicationShouldTerminate:`). – Ken Thomases Oct 05 '15 at 01:30
  • Good thought. Double-checked both their spelling. Still no break before exiting. – David Oct 05 '15 at 01:34
  • One more edit with screenshot. Does that look correct? – David Oct 05 '15 at 01:43