NSArrayController and table column bindings retain/dealloc woes
NSArrayController and table column bindings retain/dealloc woes
- Subject: NSArrayController and table column bindings retain/dealloc woes
- From: Keith Blount <email@hidden>
- Date: Mon, 17 Nov 2008 04:00:10 -0800 (PST)
Hi,
I know there have been historic problems with NSArrayController getting retained too many times when bound to File's Owner and so forth, causing dealloc problems, but my problem is slightly different... I've been through the archives and searched the docs etc, but have yet to find a solution.
I have an NSArrayController and a table with its columns bound to values in my array controller. I set the content programmatically to get around the retain problems that can be caused by setting the content in IB. So far, so good.
However, when my program closes, the array controller still has too high a retain count - it's retain count is 7 in -dealloc, so it never gets released properly. Investigating this, it turns out that this is caused by the table view column bindings. I have two columns bound to the controller and one button bound to the -canRemove value. These three bindings must retain the controller twice, causing 6 extra retains on the controller.
Now, I tested a similar set up in a new Xcode project, with File's Owner left as the standard MyDocument, and everything worked fine - the retain count was 7, just like in my project, but upon deallocation everything got released correctly and the array controller was released as it should.
Which leads me to the big difference in my project... The File's Owner in my nib file is not an NSDocument or an NSWindowController, but my own custom view controller (my app runs on Tiger and Leopard so I can't use Leopard's new NSViewController - instead I rolled my own back on Tiger). My custom view controller just holds onto the top level nib objects and then releases them in -dealloc, as follows:
- (id)initWithViewNibName:(NSString *)nibName;
{
if (self = [super init])
{
if (!nibName)
{
[self release];
return nil;
}
// By using NSNib, we can get a reference to all of the top-level objects within
// the nib when unarchiving it. This allows us to release all of those objects
// (which is our responsibility) on dealloc without having to create an outlet
// for all of them.
NSNib *nib = [[[NSNib alloc] initWithNibNamed:nibName bundle:nil] autorelease];
NSArray *topItems;
if (![nib instantiateNibWithOwner:self topLevelObjects:&topItems])
{
[self release];
return nil;
}
topLevelNibObjects = [topItems copy];
viewNibName = [nibName retain]; // Save the nib name
}
return self;
}
- (void)dealloc
{
[viewNibName release];
// Release all of the top-level objects in the nib file
[topLevelNibObjects makeObjectsPerformSelector:@selector(release)];
[topLevelNibObjects release];
[super dealloc];
}
I am thinking that maybe NSDocument and NSWindowController do a bit more than this and possibly somehow unbind everything so that these retain problems are avoided. Is that the case? And if so, does anybody know how?
I'd be very grateful if anyone can give me some advice on how to go about resolving these issues... Obviously one solution would be to manually unbind all of the columns, but I was hoping that I could implement a more general solution in my view controller subclass if that is where the problem lies.
Many thanks in advance and all the best,
Keith
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden