views:

25

answers:

2

In the Implementation Overview section of the NSPersistentDocument Core Data Tutorial it says:

  1. One issue with creating the new top-level object in the nib file is that when you use bindings an object retains other objects to which it is bound. This means that bindings must be broken to ensure there are no retain cycles when a document is closed. Moreover, since the nib file the new controller owns contains top level objects and the controller’s class does not inherit from NSWindowController, you need to release the top level objects when the window is closed.

Why not just have the controller inherit from NSWindowController? Is there a reason this would not work? Or was this just a matter of style?

A: 

In the example, its talking about controlling a sheet instead of a window. A sheet is technically a window component and not a window itself so it can't use a NSWindowController subclass as a controller. A window controller does not know how to handle a window owned by another window.

The text above is just reminding you that although the sheet controller looks very much like a window controller it is not one and that you have to manually handle releasing that is handled automatically by the window controller.

TechZen
This answer sounds perfectly reasonable, but in fact before I got it I went ahead and tried… and not only does subclassing NSWindowController work, it saves quite a bit of code! It seems this is either a style thing or it's something that was made to work sometime after the example was written.
Kaelin Colclasure
I think the problem you may run into is that a window controller automatically responds to a far wider range of events than a sheet needs. A window controller assumes it controlling an independent window. I would test throughly before releasing to make sure the sheet does not behave like a window e.g. closing without a transition.
TechZen
Always good advice! I will make sure to test thoroughly before release.
Kaelin Colclasure
A: 

As commented below, I did get this to work with an NSWindowController subclass, and it does seem to save quite a bit of code.

Here is my subclass header:

#import <Cocoa/Cocoa.h>

@interface NewAccountSheetController : NSWindowController {
@private
    BOOL isValidForInsert;
    NSManagedObjectContext * managedObjectContext;
    NSObjectController * objectController;
    NSObjectController * targetController;
}

@property (setter=setValidForInsert:) BOOL isValidForInsert;
@property (nonatomic, retain) IBOutlet NSManagedObjectContext * managedObjectContext;
@property (nonatomic, retain) IBOutlet NSObjectController * objectController;
@property (nonatomic, retain) IBOutlet NSObjectController * targetController;

- (void)beginSheetForWindow:(NSWindow *)window;

- (IBAction)endSheet:(id)sender;

@end

And here is the implementation in a Pastebin.

I have no good idea how to describe the required bindings, etc. but if you're familiar with the above tutorial they should be straightforward to extrapolate… I think. :-)

Kaelin Colclasure