In the Implementation Overview section of the NSPersistentDocument Core Data Tutorial it says:
…
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?
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. :-)
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.
Related
I've been trying to find a way to set the delegates on my custom classes as Outlets so I can connect them via IB just like one does with an UIKit Class but I haven't been able to do this, is this even possible?
Yes you will need to the IBOutlet keyword to the delegate property.
Like:
#property (nonatomic, assign) IBOutlet id <YourDelegateClass> delegate;
I've just ported my app from Garbage Collection to ARC using the Xcode tool. When my app creates a new window, the window immediately vanishes. Under GC, the window remained visible.
I understand that in ARC, any object that doesn't have a strong pointer to it disappears. I have a strong pointer from my NSDocument-subclass object to the window that belongs to it, but the NSWindow disappears immediately after being created anyway.
Do I need to have a strong pointer to the new NSDocument-subclass object? And if so, what does that pointer belong to?
- (IBAction)importLegacyDocument:(id)sender{
myDocument* theDocument = [[myDocument alloc]init];
NSWindowController* theWindowController;
theWindowController =[[NSWindowController alloc]
initWithWindowNibName:#"myDocument" owner: theDocument];
[theDocument makeWindowControllers];
[theDocument showWindows];
//WINDOW VANISHES IMMEDIATELY AFTER IT HAS BEEN CREATED
}
Thanks very much in advance to all for any info!
Yes you should have a reference to the document. Any objects you create inside a method will be destroyed if there are not being retained. The same goes for your NSWindowController instance in that code as well.
#property (strong, nonatomic) myDocument *theDocument;
#property (strong, nonatomic) NSWindowController *theWindowController
(Your AppDelegate would be a good place to declare those properties)
Then assign the created instances to your properties:
self.theDocument = [[myDocument alloc] init];
self.theWindowController = [[NSWindowController alloc] initWithWindowNibName:#"myDocument" owner:self.theDocument];
And as a side note - The Objective-C convention is to name classes with uppercase letters so myDocument should be MyDocument
Hope this helps!
Yes, and the correct place for that strong reference is the nsdocumentcontroller singleton.
You should create new documents using nsdocumentcontroller's methods rather than alloc/init. This will automatically add new documents to the document controller and remove them when the document is closed.
I am trying to access an NSMatrix object called "matrix" from my code. The object is generated in a NIB, but I keep having problems to access the object that was generated in the interface builder.
If my NSDocument has an NSMatrix *matrix, what should I do in the interface builder to link these two? And preferably, to use the initial layout from IB?
Thanks!
I think you are trying to create an outlet to the matrix. Just create a property in your .h file between the #interface and #end keywords:
#property (nonatomic) IBOutlet NSMatrix* myMatrix;
and then hold down the ctrl key and drag from 'File Owner' to the matrix object in IB. Make sure you
#synthesize myMatrix;
in your .m file between the #implementation and #end keywords and you should be able to access all of the properties via dot notation or message calls using:
self.myMatrix.somePropertyHere
I hope that helps!
Is it possible to access the NSControl on a NSWindow using tag?
I used the code below but it warned
NSWindow may not response to viewWithTag
NSButton *a=(NSButton * )[self.window
viewWithTag:tag];
Welcome any comment
Thanks
interdev
Unlike UIWindow in Cocoa Touch, NSWindow does not inherit from NSView, and thus does not implement that method. You probably want to get the contentView of the window, and then look up the tag on that.
Create an NSView in your .h file called 'view'.
In IB, highlight the View under the Window and connect it to the 'File's Owner' view from step 1.
Then you can use viewWithTag.
file.h
#property (strong, nonatomic) IBOutlet NSView * view;
file.m
[(NSTextField*)[self.view viewWithTag:(1)] setStringValue: #"MyStringName"];
I know some mechanism of outlet connection when loading NIB, but I am not sure. So I'm asking some questions to ensure my knowledge. I assumed these things all true, but It's hard to find mention about these on reference documentation. Please point wrong and right things.
I have an IBOutlet defined like this: (Of course it's not recommended way)
#implementation
{
IBOutlet id var1;
}
#end
NIB loader (alloc | retain) & autorelease all top-level objects. So it will be dealloc on runloop turn ends without additional retain.
Connecting IBOutlets are done with KVC.
KVC uses accessor method primarily.
KVC uses setValue:forKey secondarily. And the IBOutlet will be handled by this method because there's no declared property or access method.
setValue:forKey retains the new value object.
setValue:forKey releases the old value object.
So top-level object connected to the IBOutlet will be retained once. So I have to release it to dealloc. This is why I must release objects connected to IBOutlet on dealloc method.
If the object connected another IBOutlet like the IBOutlet, it should be released once more to be dealloc.