Pregunta

What I would like to know is how does the window controller I initialize with

NSWindowController *c=[[NSWindowController alloc] initWithWindowNibName:@"Win" owner:myObj]

know which window it should control in the Win.xib file if myObj is not the controller itself? Normally I set the window controller as the owner so that I can set its window in IB with on outlet. Is memory management done all by the window controller even if it is not the owner?

¿Fue útil?

Solución

The window controller will do the memory management of the top-level objects even if it's not the owner. From the NSWindowController class reference:

Regardless of who is the file’s owner, the window controller is responsible for freeing all top-level objects in the nib file it loads.

The window controller is normally the owner of the NIB, though, and connecting its window outlet is usually how it knows which window to control. One could also use the -setWindow: method to set it explicitly.

It's conceivable that NSWindowController searches the NIB's top-level objects for a window to control if the outlet isn't hooked up, but I don't think it does that.

Have you observed some behavior that you don't understand? What was it?

Otros consejos

This method exists for the case that you have a document based app; see NSDocument. In that case you'd make an instance of NSDocument the owner of the NIB file (NSDocument has a -setWindow: method but no getter for it). The controller will still get to know its window from the document instance. Code would roughly be:

NSDocument * document = ...;
NSWindowController * winCtrl = [[NSWindowController alloc]
   initWithWindowNibName:@"SomeNib" owner:document];
[document addWindowController:winCtrl];
[winCtrl loadWindow];

Now the document is owner of the NIB file but the window controller still receives a reference to the window that is assigned to the document.

Of course this code is only for demonstration purposes, the correct way to do it is actually to sub-class NSDocument, override makeWindowControllers, and initiate all required controllers there.

If your document always only has a single window from a single NIB file, you can also just set the NSDocument property windowNibName to the name of your NIB file and then call the default makeWindowControllers implementation, which roughly does the following:

NSWindowController * winCtrl = [[NSWindowController alloc]
   initWithWindowNibName:self.windowNibName owner:self];
[self addWindowController:winCtrl];

Also check out the GNUStep implementation of NSWindowController, which may be different than the one from Apple (the one from Apple isn't open source, so we cannot know) but it should be equal in behavior:

- (void) loadWindow
{
  NSDictionary *table;

  if ([self isWindowLoaded]) 
    {
      return;
    }

  table = [NSDictionary dictionaryWithObject: _owner forKey: NSNibOwner];
  if ([NSBundle loadNibFile: [self windowNibPath]
        externalNameTable: table
        withZone: [_owner zone]])
    {
      _wcFlags.nib_is_loaded = YES;

      if (_window == nil  &&  _document != nil  &&  _owner == _document)
        {
          [self setWindow: [_document _transferWindowOwnership]];
        }
      else
        {
          // The window was already retained by the NIB loading.
          RELEASE(_window);
        }
    }
  else
    {
      if (_window_nib_name != nil)
        {
      NSLog (@"%@: could not load nib named %@.nib", 
         [self class], _window_nib_name);
    }
    }
}

Source: https://github.com/gnustep/libs-gui/blob/master/Source/NSWindowController.m

It will obtain the window from its document using the private method _transferWindowOwnership but only if no window is set after loading, a document is set and this document has been set to be the owner of the loaded NIB file.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top